使用Spring Boot + JUnit5 + Kotlin编写测试

最新消息

本文是在Spring Boot 2.1发布之前所写的。从2.1开始,不再需要使用@ExtendWith(SpringExtension::class)注解来标注各种测试注解,因此如果您正在使用@SpringBootTest注解,就无需再添加@ExtendWith(SpringExtension::class)了。

首先

本文介绍了在使用Spring Boot项目中如何引入JUnit5,不涉及到JUnit5的详细描述方法,请注意。另外,本文假设以下配置:
– Spring Boot版本:2.x
– JUnit5
– Kotlin版本:1.2.x
– Gradle版本:4.6以上

准备

首先创建一个Spring Boot项目。
我认为使用Kotlin创建项目时,build.gradle 文件将采用以下类似的描述。

在创建项目时生成的build.gradle文件:build.gradle

buildscript {
ext {
kotlinVersion = ‘1.2.41’
springBootVersion = ‘2.0.3.RELEASE’
}
repositories {
mavenCentral()
}
dependencies {
classpath(“org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}”)
classpath(“org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}”)
classpath(“org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}”)
}
}

apply plugin: ‘kotlin’
apply plugin: ‘kotlin-spring’
apply plugin: ‘eclipse’
apply plugin: ‘org.springframework.boot’
apply plugin: ‘io.spring.dependency-management’

group = ‘com.example’
version = ‘0.0.1-SNAPSHOT’
sourceCompatibility = 1.8

compileKotlin {
kotlinOptions {
freeCompilerArgs = [“-Xjsr305=strict”]
jvmTarget = “1.8”
}
}

compileTestKotlin {
kotlinOptions {
freeCompilerArgs = [“-Xjsr305=strict”]
jvmTarget = “1.8”
}
}

repositories {
mavenCentral()
}

dependencies {
compile(‘org.springframework.boot:spring-boot-starter’)
compile(“org.jetbrains.kotlin:kotlin-stdlib-jdk8”)
compile(“org.jetbrains.kotlin:kotlin-reflect”)
testCompile(‘org.springframework.boot:spring-boot-starter-test’)
}

接下来,我们将描述在Spring Boot中使用JUnit5所需的设置。
注意,由于Gradle版本4.6开始支持JUnit5,请使用此版本或更高版本。
将dependencies后面的描述更改为以下内容。

dependencies {
    compile('org.springframework.boot:spring-boot-starter')
    compile("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    compile("org.jetbrains.kotlin:kotlin-reflect")
    testCompile('org.springframework.boot:spring-boot-starter-test') {
       exclude module: 'junit' // 1
    }
    testImplementation('org.junit.jupiter:junit-jupiter-api') // 2
    testRuntimeOnly('org.junit.jupiter:junit-jupiter-engine') // 2
}

test {
    useJUnitPlatform() // 3
}
    1. 由于spring-boot-starter-test默认包含了4系,所以我们将其移除。

 

    1. 我们添加了junit-jupiter-api和junit-jupiter-engine。

 

    通过这个配置,我们启用了JUnit5。

准备工作已经全部完成。

创建测试代码

假设有一个用JUnit4编写的测试文件,其示例如下。

import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.junit.jupiter.api.assertThrows
import org.junit.runner.RunWith
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit4.SpringRunner

class Color {
    fun getRed(): String = "FF0000"
    fun throwException() { throw Exception() }
}

@RunWith(SpringRunner::class)
@SpringBootTest
class ColorTests {

    @Before
    fun setup() {
        // do something
    }

    @Test
    fun getRedTest() {
        Assert.assertEquals("FF0000", Color().getRed())
    }

    @Test
    fun throwExceptionTest() {
        assertThrows<Exception> {
            Color().throwException()
        }
    }
}

如果用JUnit5进行编写,则如下所示。

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit.jupiter.SpringExtension

class Color {
    fun getRed(): String = "FF0000"
    fun throwException() { throw Exception() }
}

@ExtendWith(SpringExtension::class) // 1
@SpringBootTest
class ColorTests {

    @BeforeEach // 2
    fun setup() {
        // do something
    }

    @Test
    fun getRedTest() {
        assertEquals("FF0000", Color().getRed())
    }

    @Test
    fun throwExceptionTest() {
        assertThrows<Exception> {
            Color().throwException()
        }
    }
}
    1. 在JUnit5中,Runner变成了Extension,因此相关的变化也随之而来。

 

    从JUnit5开始,有一些注解发生了变化。

总结

我在簡單介紹了如何在Spring Boot中引入JUnit5的方法。

提醒需要记住的事项有4个:
1. Gradle 4.6或以上版本。
2. 从spring-boot-starter-test中移除4系。
3. 添加Junit5的依赖并启用useJUnitPlatform()。
4. 在测试类中添加注解@SpringBootTest和以下内容。

@RunWith(SpringRunner::class) // これではなく、
@ExtendWith(SpringExtension::class) // これを書く

如果有任何错误或不正确之处,请您指出,我将不胜感激。

广告
将在 10 秒后关闭
bannerAds