Since we had a look at spring and springboot in a previous article. Let review how we can test the beast! Because like all good developer, you like writing good tested code with TDD aka Test Driven Development. Where you usually start with test… 😅

Test a simple Rest spring application

Simple Get endpoint

Let’s say you have a spring REST application in kotlin with a simple endpoint. That’s all good and well, but how do you test that in Kotlin. You can usually find a lot of information online, so let’s add this one to the mix:

class Endpoints {

  @GetMapping(value = ["/hello/{name}"], produces = ["application/json"])
  fun hello(@PathVariable(value = "name") name: String) = ResponseEntity(name), HttpStatus.OK)


This is a simple hello endpoint that will return the name parameter that is sent in the url. The @RequestMapping("/v1") annotation will prepend /v1 to all endpoints define in the class.

Bring in your test dependencies

The springboot dependencies will be automatically deduced by the plugin. That’s why when importing springboot test packages you may want to exclude the old junit v4 to start fresh with mockK and Junit5.

Here would be a simplified snippet of our build.gradle.kts for our test dependencies:

plugins {
    id("org.springframework.boot") version "2.2.7.RELEASE"
    id("io.spring.dependency-management") version "1.0.7.RELEASE"

dependencies {
    testImplementation("org.springframework.boot:spring-boot-starter-test") {
        exclude(module = "junit")
        exclude(module = "mockito-core")

Although mockito should still be compatible with Kotlin, the syntax gets weird because it’s conflicting with some Kotlin key words like when(). So usually when using Kotlin, you’ll go with mockK instead.

And to avoid interferences we exclude Mockito from spring-boot-starter-test as well.

Spring application test class

Let’s create our ApplicationTest class to test our springboot REST application. Basically you would find some annotation in order to resolve the bean in the context load, specify some information and properties.

    webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
    classes = [ApplicationTest.ControllerTestConfig::class],
    properties = [""]
@ActiveProfiles(value = ["test"])
internal class ApplicationTest {

  var testRestTemplate = TestRestTemplate()

  var serverPort: Int = 0

  internal class ControllerTestConfig {
    fun foo(): Foo = mockk()
  private fun applicationUrl() = "http://localhost:$applicationPort"

You can see other annotations:

  • @SpringBootTest: Because it’s a springboot test, you can pass spring properties in properties and define some variables.
  • @ActiveProfiles(value = ["test"]): To use a different profile when spinning the spring application (you might not want a certain bean to be built for the test, or you have a test profile defined with different values.)
  • @LocalServerPort: In this case will represent the port on which your web springboot app will be hosted.
  • @TestConfiguration: This is to define the test configuration, you can mock or update beans there.

The ControllerTestConfig is here if you have some configuration you want to mock or modify for the test. For example here we are mocking the bean foo meaning that any autowire of that bean will take this mock version.

Write your first test

I came across Kotlin Unit test best practice that gives a lot of cool tips on how to test your kotlin code.

Here is a simple test to send a GET request to your application using the testRestTemplate. A springboot test tool to make REST request, so that you can test the behaviour of your application. You can check and assert the result to make sure everything is alright.

fun simpleGetTest() {
  val result =
      URI(applicationUrl() + "/v1/hello/world"),

  Assertions.assertEquals(HttpStatus.OK, result.statusCode)
  Assertions.assertEquals("world", result.body)

You can see the result is in a to get the result body as a String. Be careful, if you set the result body type to you won’t get the body at all (even if there’s one).

Mock your beans

Obviously here you’re testing end to end your application, and in some case it may connect to other part of the system. In order to simplify the testing, you can mock external dependencies for your test to run smoothly.

If there are bits of logic of a spring component you want to test, you can still “autowire” them in another test file, Thus you can test different niche behaviour or custom error handling.

Using mockK only

Here is how you would do that with our @Bean foo from the previous example. You would set a special test profile here and use for the real bean "!test" to avoid interferences. Be sure if you have a missing bean error to add your test configurations class in classes in your @SpringBootTest

@Profile(value = ["test"])
fun foo(): Foo {
  val fooClient: Foo = mockk(relaxed = true)
  every { } just Runs
  every { fooClient.isOpen() } returns true
  every { fooClient.close() } throws RuntimeException()
  return fooCLient

So here you can see three behaviours that was defined for our Beans. We define the behaviour of some method, define a return value or throw an exception. This way we can test some custom behaviour.

With springmockk

However if you prefer a syntax closer to Mockito, you can use springMockk with mockK by adding this dependency from your gradle file:


Then you can just define your mocked bean like:

lateinit var foo: Foo

And then you can use “ every { … } + behaviour” the mockK way to define the behaviour of the mockkBean in each test. Make sure you have Mocktio excluded for this one, as it’s strongly recommended.