How does kotlintest test spring boot application

5.9k views Asked by At

The integration test of Spring boot application always starts the web server firstly.

The simplest test of spring boot test looks like below, how does migrate it using kotlintest instead?

@ExtendWith(SpringExtension::class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ReportApplicationTests {

    @Test
    fun `Server can be launched`() {
    }

}
2

There are 2 answers

4
Yoni Gibbs On BEST ANSWER

Here's how I've got it set up: firstly, make sure to reference JUnit 5 instead of 4, e.g. I've got this in the dependencies section of my build.gradle:

testImplementation "org.springframework.boot:spring-boot-starter-test:${springBootVersion}"
testImplementation "org.jetbrains.kotlin:kotlin-test"
testImplementation "org.jetbrains.kotlin:kotlin-test-junit"
testImplementation "io.kotlintest:kotlintest-extensions-spring:3.1.10"
testImplementation 'io.kotlintest:kotlintest-runner-junit5:3.1.10'
testImplementation "org.junit.jupiter:junit-jupiter-api:5.3.1"
testImplementation "org.junit.jupiter:junit-jupiter-engine:5.3.1"

Also add this to build.gradle:

test {
    useJUnitPlatform()
}

Then in your integration test class have this (notice the override of listeners, without which it won't work):

import org.springframework.boot.test.context.SpringBootTest
import io.kotlintest.spring.SpringListener

@SpringBootTest(
        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
        classes = [MyApplication::class])
class MyTestStringSpec : StringSpec() {
    override fun listeners() = listOf(SpringListener)

    init {
        // Tests go in here
    }
}

Obviously you can replace StringSpec with any of the other Kotlin Test testing styles, e.g. FunSpec, ShouldSpec, etc.

2
LeoColman On

Update: From version 4.3+, somethings have changes.

Version 4.3+ (newer)

KotlinTest was renamed to Kotest. The SpringExtension is the class to integrate with spring. The documentation on how to use it is pretty simple.

In addition to Kotest dependency, you should also add SpringExtension:

testImplementation("io.kotest.extensions:kotest-extensions-spring:1.0.0")

and then include SpringExtension to your extensions. From then on you can use everything Spring Boot has to offer in tests, such as ContextConfiguration and others:

@SpringBootTest
class MyTestSpec : FunSpec() {
   override fun extensions() = listOf(SpringExtension)

   init {
     test("I'm inside a Spring context!") { }
   }
}

Version 3.3.2 (very old)

Kotlintest has a very nice guide on how to setup Spring Extension to test Spring Framework.

Basically, in addition to KotlinTest dependency, you also add it's Spring Extension:

testImplementation ("io.kotlintest:kotlintest-runner-junit5:3.3.2") // KT dependency
testImplementation("io.kotlintest:kotlintest-extensions-spring:3.3.2") // KT Spring Extensions

And then you include the SpringListener and SpringBootTest to your code:

import org.springframework.boot.test.context.SpringBootTest
import io.kotlintest.spring.SpringListener

@SpringBootTest
class SpringExample : FreeSpec() {

    override fun listeners() = listOf(SpringListener)

    init {
        "Verify context loads" {

        }
    }
}

You don't need to add SpringListener to every test you create, you can configure it globally using ProjectConfig. ProjectConfig is explained in KotlinTest Documentation