什么是@BeforeAll在Kotlin的正确解决方法

Gri*_*hev 11 java junit mockito kotlin junit5

目前,JUNIT5 API仅允许@BeforeAll用于静态方法

所以,如果这样做,这将无法编译:

@BeforeAll
  fun setup() {
    MockitoAnnotations.initMocks(this)
    mvc = MockMvcBuilders.standaloneSetup(controller).build()
}
Run Code Online (Sandbox Code Playgroud)

所以为了在Kotlin中使用静态方法,我必须像这样放入伴随对象:

companion object {
    @JvmStatic
    @BeforeAll
    fun setup() {
      MockitoAnnotations.initMocks(this)
      mvc = MockMvcBuilders.standaloneSetup(smsController).build()
    }
}
Run Code Online (Sandbox Code Playgroud)

这将编译,但我无法访问父类中的变量.那么用Kotlin调用JUnit5的@BeforeAll会是什么惯用法呢?

edu*_*nti 15

您可以访问伴随对象内的变量:

    companion object {

        private lateinit var objectToBeInitialized: Test

        @BeforeAll
        @JvmStatic
        fun setup() {
            objectToBeInitialized = Test()
        }
    }
Run Code Online (Sandbox Code Playgroud)


Uli*_*ses 9

JUnit 5具有@TestInstance(PER_CLASS)可用于此目的的注释.它启用的功能之一是非静态BeforeAllAfterAll方法:

@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)
Run Code Online (Sandbox Code Playgroud)

  • Android Studio 无法解析 PER_CLASS。`@TestInstance(TestInstance.Lifecycle.PER_CLASS)` (2认同)

mie*_*sol 8

如文档中所述@BeforeAll

表示注解的方法应该在当前类中的所有@Test方法之前执行;类似于 JUnit 4 的 @BeforeClass。这些方法必须是静态的并且是继承的。

以上对 Kotlin 和 Java 都是正确的。请记住,默认情况下,Junit 将为每个测试用例创建一个单独的测试类实例。它只@BeforeAll适用于静态方法是有道理的,因为它应该在当前测试用例的任何代码之前被调用。静态方法无法访问实例成员,因为它可以在没有实例的情况下被调用

正如 Spring 文档中所述:

另一方面,“standaloneSetup”更接近于单元测试。

该示例表明您应该像这样使用实例成员:

class StandaloneTest {
  val smsController = ... // create instance of controller
  val MockMvcBuilders.standaloneSetup(smcController).build()
}
Run Code Online (Sandbox Code Playgroud)

的用处@BeforeAll是有限的,通常应该避免,因为它可能会鼓励测试用例之间的运行时依赖性。