Spring Boot 中JUnit单元测试问题
条评论最近在读 Spring in Action 4th,书中包含不少单元测试的样例,基础格式:(示例语言 Kotlin
)
1 | package springinaction |
在 Spring 的项目开发中,单元测试是常见的临时测试代码模块的方式,以上格式主要是包含两个类级注解 @RunWith
,@ContextConfiguration
,其中 @RunWith
如其名,意思是让当前的单元测试以怎样的环境运行,这里使用Spring的 SpringJUnit4ClassRunner
,用于在测试时自动创建Spring的应用上下文 (Context 我更偏向于翻译成运行环境),该 Context 具体做怎样的配置在于 @ContextConfiguration
注解中所传入的基于Java的配置类,这个类应至少标上 @Configuration
注解,例如:
1 | package springinaction |
其中,@ComponentScan
注解不是必需的,其作用是查找与本类在同一 package 下且通过注解方式注入 Spring 容器的 JavaBean (未提供参数,则默认在本类所在的package中扫描) 并将其创建添加至容器。
为节省配置Spring依赖的时间,我使用 Spring Boot 和 Gradle 构建项目以做示例实现,但在项目构建结束后无法找到 @RunWith
注解,虽说在Spring Boot中可使用 @SpringBootTest
注解作为代替,但是我仍旧想解决 @RunWith
无法找到的问题,Google一下并未找到解决方案,或说大多解决方案是添加 spring-boot-test-starter
相关依赖,但这不是问题的原因。
于是,查找官方文档,在JUnit5的 User Guide 中,关于 Migrating from JUnit4 章节中找到如下描述:
3.2. Migration Tips
The following are topics that you should be aware of when migrating existing JUnit 4 tests to JUnit Jupiter.
- Annotations reside in the
org.junit.jupiter.api
package.- Assertions reside in
org.junit.jupiter.api.Assertions
.- Assumptions reside in
org.junit.jupiter.api.Assumptions
.
- Note that JUnit Jupiter 5.4 and later versions support methods from JUnit 4’s
org.junit.Assume
class for assumptions. Specifically, JUnit Jupiter supports JUnit 4’sAssumptionViolatedException
to signal that a test should be aborted instead of marked as a failure.@Before
and@After
no longer exist; use@BeforeEach
and@AfterEach
instead.@BeforeClass
and@AfterClass
no longer exist; use@BeforeAll
and@AfterAll
instead.@Ignore
no longer exists: use@Disabled
or one of the other built-in execution conditions instead
- See also JUnit 4 @Ignore Support.
@Category
no longer exists; use@Tag
instead.@RunWith
no longer exists; superseded by@ExtendWith
.@Rule
and@ClassRule
no longer exist; superseded by@ExtendWith
and@RegisterExtension
- See also Limited JUnit 4 Rule Support.
之前的注解类现在位于 org.junit.jupiter.api
包中,经查看,在新的 JUnit5 中此前 @RunWith
注解所在的 org.junit.runner
包已经不存在,且文档中提到 @RunWith
no longer exists; superseded by @ExtendWith.
,即 @RunWith
将由 @ExtendWith
替代。至此,这个问题解决了,只要替换下注解节即可。
但实际上 @ExtendWith
与 @RunWith
有所区别,@ExtendWith
无法接收 SpringJUnit4ClassRunner::class
作为参数。
1 | ({ ElementType.TYPE, ElementType.METHOD }) |
从源码可以看到它接收任意一个实现了 Extension
接口的Java类 数组 ,那么为了得到与 @RunWith(SpringJUnit4ClassRunner::class)
等价的效果,需要在 @ExtendWith
注解中传入 SpringExtension::class
,即 @ExtendWith(SpringExtension::class)
(传入单个值可不以数组形式)。为了更加理解 Extension 的作用,我查看源码,在 SpringExtension 的类注释中看到以下描述:
1 | /** |
即,SpringExtension将Spring的测试上下文框架集成到JUnit 5的Jupiter编程模型中。
对于 JUnit Jupiter,官方文档是这样解释的:
JUnit Jupiter is the combination of the new programming model and extension model for writing tests and extensions in JUnit 5. The Jupiter sub-project provides a
TestEngine
for running Jupiter based tests on the platform.
它是新的 编程模型 与 扩展模型 的结合,以我自己的理解方式,新的编程模型,即在新的 JUnit5 中较 Junit4 新的改进,很表面的变化可以说包含了一些新的用于测试的注解与注解更名,而大的变化在于与扩展模型的结合,在 JUnit4.0 中,对一个测试类而言,只有一种扩展JUnit的方式,即创建一个新的Runner,然后在测试类上添加 @RunWith(MyRunner::class)
注解,也就是形如前文描述的那样:
1 |
|
因为仅有一种扩展方式,因此
- 本文链接:https://blog.charjin.top/2020/01/17/spring-junit5/
- 版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 CN 许可协议。转载请注明出处!
分享