目前,JUnit 5API只允许在静态方法上使用@BeforeAll
。
所以如果我做这样的事情,它不会编译:
@BeforeAll
fun setup() {
MockitoAnnotations.initMocks(this)
mvc = MockMvcBuilders.standaloneSetup(controller).build()
}
为了在静态编程语言中拥有静态方法,我必须使用配套对象
,如下所示:
companion object {
@JvmStatic
@BeforeAll
fun setup() {
MockitoAnnotations.initMocks(this)
mvc = MockMvcBuilders.standaloneSetup(smsController).build()
}
}
这将编译,但我无法访问父类中的变量。那么使用静态编程语言调用JUnit 5@BeforeAll
的惯用方法是什么?
JUnit 5具有可用于此目的的@TestInstance(PER_CLASS)
注释。它启用的特性之一是非静态的BeforeAll
和AfterAll
方法:
@TestInstance(PER_CLASS)
class BeforeAllTests {
lateinit var isInit = false
@BeforeAll
fun setup() {
isInit = true
}
@TestFactory
fun beforeAll() = listOf(
should("initialize isInit in BeforeAll") {
assertTrue(isInit)
}
)
}
fun should(name: String, test: () -> Unit) = DynamicTest.dynamicTest("should $name", test)
您可以访问配套对象中的变量:
companion object {
private lateinit var objectToBeInitialized: Test
@BeforeAll
@JvmStatic
fun setup() {
objectToBeInitialized = Test()
}
}
如@BeforeAll
的留档所述:
表示带注释的方法应在当前类中的所有@Test方法之前执行;类似于JUnit 4的@BeforeClass。此类方法必须是静态的并且是继承的。
以上对于静态编程语言和Java都是如此。请记住,默认情况下,Junit将为每个测试用例创建一个单独的测试类实例。@BeforeAll
只适用于静态方法,因为它应该在当前测试用例的任何代码之前调用。静态方法无法访问实例成员,因为它可以在没有实例的情况下调用。
如Spring留档所述:
另一方面,“标准设置”更接近于单元测试。
该示例表明您应该像这样使用实例成员:
class StandaloneTest {
val smsController = ... // create instance of controller
val MockMvcBuilders.standaloneSetup(smcController).build()
}
@BeforeAll
的有用性是有限的,通常应该避免,因为它可能会鼓励测试用例之间的运行时依赖关系。