Kotlin和JUnit 5 @BeforeAll

介绍

Kotlin中 ,类没有静态方法 。 但是,可以使用伴随对象的概念为调用者提供Java等效语义。 这篇文章将详细介绍如何支持JUnit 5 @BeforeAll和@AfterAll批注,这取决于测试类中静态方法的优先级。

Java中的BeforeAll和AfterAll

Junit 5 @BeforeAll带注释的方法在所有测试之前执行,@ AfterAll在所有测试之后被执行。 这些注释应应用于静态方法:

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Junit5BeforeAllTest {

    private static final Logger LOGGER = LoggerFactory.getLogger(Junit5BeforeAllTest.class);
    
    @BeforeAll
    static void beforeAll() {
        LOGGER.info("beforeAll called");    
    }
    
    @Test
    public void aTest1() {
        LOGGER.info("aTest1 called");
        LOGGER.info(this.toString());        
    }
    
    @Test
    public void aTest2() {
        LOGGER.info("aTest2 called");
        LOGGER.info(this.toString());
    }
    
    @AfterAll
    static void afterAll() {
        LOGGER.info("afterAll called");        
    }
}

粗略的流程是– JUnit平台调用带注释的“ @BeforeAll”方法,然后
对于每个测试,它都会创建测试类的实例并调用该测试。 执行完所有测试后,将调用带注释的“ @AfterAll”静态方法,该方法由日志证实,请参见实例id(来自Object的toString())如何不同:

2018-03-28 17:22:03.618  INFO   --- [           main] c.p.cookbook.Junit5BeforeAllTest         : beforeAll called
2018-03-28 17:22:03.652  INFO   --- [           main] c.p.cookbook.Junit5BeforeAllTest         : aTest1 called
2018-03-28 17:22:03.653  INFO   --- [           main] c.p.cookbook.Junit5BeforeAllTest         : com.pivotalservices.cookbook.Junit5BeforeAllTest@7bc1a03d
2018-03-28 17:22:03.663  INFO   --- [           main] c.p.cookbook.Junit5BeforeAllTest         : aTest2 called
2018-03-28 17:22:03.664  INFO   --- [           main] c.p.cookbook.Junit5BeforeAllTest         : com.pivotalservices.cookbook.Junit5BeforeAllTest@6591f517
2018-03-28 17:22:03.669  INFO   --- [           main] c.p.cookbook.Junit5BeforeAllTest         : afterAll called

尽管可以通过以下方式对测试类进行注释,但是可以通过注释来更改JUnit 5测试的默认生命周期:

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class Junit5BeforeAllTest {
....
}

现在的好处是,@ BeforeAll和@AfterAll批注可以放置在非静态方法上,因为JUnit 5平台可以保证在进行所有测试之前,这些方法恰好是一次。 但是要注意的是,在每次测试之前都不会重置任何实例级状态。

在Kotlin之前和之后

那么这如何转化为Kotlin –

对于每个测试一个新测试实例的默认情况,等效的Kotlin测试代码如下所示:

import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.slf4j.LoggerFactory

class Junit5BeforeAllKotlinTest {

    @Test
    fun aTest1() {
        LOGGER.info("aTest1 called")
        LOGGER.info(this.toString())
    }

    @Test
    fun aTest2() {
        LOGGER.info("aTest2 called")
        LOGGER.info(this.toString())
    }

    companion object {
        private val LOGGER = LoggerFactory.getLogger(Junit5BeforeAllTest::class.java)


        @BeforeAll
        @JvmStatic
        internal fun beforeAll() {
            LOGGER.info("beforeAll called")
        }

        @AfterAll
        @JvmStatic
        internal fun afterAll() {
            LOGGER.info("afterAll called")
        }
    }
}

一个带有@JvmStatic注释的方法的Kotlin 伴随对象可以完成这项工作。

修改生命周期的情况比较简单:

import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.slf4j.LoggerFactory

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class Junit5BeforeAllKotlinTest {

    private val LOGGER = LoggerFactory.getLogger(Junit5BeforeAllTest::class.java)

    @BeforeAll
    internal fun beforeAll() {
        LOGGER.info("beforeAll called")
    }

    @Test
    fun aTest1() {
        LOGGER.info("aTest1 called")
        LOGGER.info(this.toString())
    }

    @Test
    fun aTest2() {
        LOGGER.info("aTest2 called")
        LOGGER.info(this.toString())
    }


    @AfterAll
    internal fun afterAll() {
        LOGGER.info("afterAll called")
    }
}

我个人偏爱伴侣对象方法,因为我喜欢在执行测试方法之前确定测试实例的确定性状态的想法。 该方法的另一个优点是基于Spring Boot的测试,您希望Spring仅在调用@BeforeAll带注释的方法之后才对测试实例进行操作(注入依赖项,解析属性等),为使这一点更加具体,请考虑以下示例:

import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.context.annotation.Configuration
import org.springframework.test.context.junit.jupiter.SpringExtension


@ExtendWith(SpringExtension::class)
@SpringBootTest
class BeforeAllSampleTest {

    @Value("\${some.key}")
    private lateinit var someKey: String

    
    companion object {
        @BeforeAll
        @JvmStatic
        fun beforeClass() {
            System.setProperty("some.key", "some-value")
        }

        @AfterAll
        @JvmStatic
        fun afterClass() {
            System.clearProperty("some.key")
        }
    }

    @Test
    fun testValidateProperties() {
        assertThat(someKey).isEqualTo("some-value")
    }

    @Configuration
    class SpringConfig
}

如果将生命周期更改为“ @TestInstance(TestInstance.Lifecycle.PER_CLASS)”,则这种测试根本无法进行

参考

这个stackoverflow答案有助于我理解Kotlin对JUnit 5的细微差别。

翻译自: https://www.javacodegeeks.com/2018/03/kotlin-and-junit-5-beforeall.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值