【问题标题】:What is proper workaround for @BeforeAll in KotlinKotlin 中 @BeforeAll 的正确解决方法是什么
【发布时间】:2016-11-25 18:22:20
【问题描述】:

目前 JUnit 5 API 仅允许 @BeforeAll 用于静态方法。

所以如果我做这样的事情,它不会编译:

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

为了在 Kotlin 中有一个静态方法,我必须像这样使用companion object

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

这将编译,但我无权访问父类中的变量。那么使用 Kotlin 调用 JUnit 5 @BeforeAll 的惯用方式是什么?

【问题讨论】:

  • 我觉得你用@BeforeAll是不对的。为什么不使用@BeforeEach
  • 我的印象是 JUnit 5 只实例化测试类一次,但看起来它对每个测试用例都进行了。 @BeforeAll@BeforeEach 之间没有区别……几乎没有区别

标签: java junit mockito kotlin junit5


【解决方案1】:

@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】:

    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)
    

    【讨论】:

    • 也可以通过junit-platform.properties 文件将PER_CLASS 定义为默认值,有关详细信息,请参阅Spring Kotlin 文档:docs.spring.io/spring/docs/current/spring-framework-reference/…
    • @SébastienDeleuze 不错的提示!
    • Android Studio 无法解析 PER_CLASS。 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
    【解决方案3】:

    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() { }
    }
    

    【讨论】:

      【解决方案4】:

      @SpringBootTest 中,这是一个简单的解决方案。请注意,@BeforeAll fun 可以使用 Spring 注入的属性。

      @SpringBootTest(classes = [Application::class])
      @TestInstance(TestInstance.Lifecycle.PER_CLASS)
      class MyTest {
      
          @Autowired
          lateinit var someBean: SomeBean
      
          lateinit var propertyForAll: PropertyForAll
      
          @BeforeAll
          fun setup() {
              propertyForAll = PropertyForAll(someBean.valueXyz())
          }
      
          @Test
          fun `First test`() {
              val something = propertyForAll.findSomething("Banana")
              // test continues
          }
      
          @Test
          fun `Second test`() {
              val something = propertyForAll.findSomething("Orange")
              // test continues
          }
      }
      

      值得一看:

      【讨论】:

        【解决方案5】:

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

            companion object {
        
                private lateinit var objectToBeInitialized: Test
        
                @BeforeAll
                @JvmStatic
                fun setup() {
                    objectToBeInitialized = Test()
                }
            }
        

        【讨论】:

        • 完美答案。
        猜你喜欢
        • 2012-10-10
        • 2010-10-10
        • 1970-01-01
        • 2013-10-27
        • 2014-04-08
        • 1970-01-01
        • 2015-03-14
        • 2022-11-15
        • 2021-10-30
        相关资源
        最近更新 更多