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

时间:2016-07-22 00:34:11

标签: java junit mockito kotlin junit5

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

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

@BeforeAll
  fun setup() {
    MockitoAnnotations.initMocks(this)
    mvc = MockMvcBuilders.standaloneSetup(controller).build()
}

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

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

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

4 个答案:

答案 0 :(得分:5)

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)

答案 1 :(得分:4)

@BeforeAll的文件中所述:

  

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

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

正如Spring文档中所述:

  

" standaloneSetup"另一方面,它更接近于单元测试。

该示例显示您应该只使用实例成员:

class StandaloneTest {
  val smsController = ... // create instance of controller
  val MockMvcBuilders.standaloneSetup(smcController).build()
}

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

答案 2 :(得分:1)

JUnit 5支持测试扩展,例如BeforeAllCallback

import org.junit.jupiter.api.extension.BeforeAllCallback
import org.junit.jupiter.api.extension.ExtensionContext

class BeforeAllTests : BeforeAllCallback {
    override fun beforeAll(context: ExtensionContext?) {
        System.out.println("Before all executed");
    }
}

在您的Kotlin测试课程中

@ExtendWith(BeforeAllTests::class)
class MyAppCoreTest : MyAppTest() {

    @Test
    fun someTest() { }
}

答案 3 :(得分:1)

您可以访问 companion 对象中的变量:

    companion object {

        private lateinit var objectToBeInitialized: Test

        @BeforeAll
        @JvmStatic
        fun setup() {
            objectToBeInitialized = Test()
        }
    }