loading...
Kotest

Testing Koin applications with Kotest

leocolman profile image Leonardo Colman Updated on ・2 min read

TL;DR - Using the KoinListener from Kotest to write tests that depend on Koin modules in a Kotest Spec

Hello, Kotliners!

In this article we will see how to test applications that use the Koin DI Framework in a Spec from the Kotest Framework. We'll take the JUnit example from Koin's documentation and enhance it with Kotest.

3 simple steps

  1. Add Kotest's Koin extensions to your build.gradle
  2. Transform your JUnit test into a Kotest Spec (or create one from scratch)
  3. Add the KoinListener to your class

Add Koin extension to your build.gradle

On your build.gradle file we'll add the Koin Extension dependency as a testImplementation. I'm assuming you already have Kotest configured. If you don't, take a look at the docs on how to do it.


I like to keep the Koin Extension definition close to my Kotest definition

build.gradle

dependencies {
    // ... Your dependencies ... 

    // Kotest
    testImplementation("io.kotest:kotest-runner-junit5:{version}")
    testImplementation("io.kotest:kotest-extensions-koin:{version}")

}

Transform a JUnit test to a Kotest Spec

For this example, we are going to use the JUnit example from the Koin docs:

class MyTest : KoinTest {

    // Lazy inject property
    val componentA : ComponentA by inject()

    // use it in your tests :)
    @Test
    fun `make a test with Koin`() {
        startKoin { modules(appModule) }

        // use componentA here!
    }
}

Converting the test

There are a lot of styles that can be used in Kotest, let's try with FunSpec

class MyTest : FunSpec(), KoinTest {


    // Lazy inject property
    val componentA : ComponentA by inject()

    init {
        test("Make a test with Koin") {
            startKoin { modules(appModule) }

            // use componentA here!
        }
    }

}

This will already work!

This example works in the same way as the JUnit code. If we add more tests to the class, we'll have to clear Koin's context. In JUnit we create a @After method. Let's see how to do this in Kotest


Add KoinListener to the class

To fix this, we can either override the afterTest function, that works similarly to @After or we can use the KoinListener to do that automatically for us! Let's try with that approach:

class MyTest : FunSpec(), KoinTest {

    override fun listeners() = listOf(KoinListener(appModule))

    // Lazy inject property
    val componentA : ComponentA by inject()

    init {
        test("Make a test with Koin") {

            // use componentA here!
        }
    }

}

With KoinListener we will have Kotest handle both Koin's start (see that we removed that line in our test!) and Koin's stop.

And that's it!

With this simple setup, you'll be able to test your Koin Application with Kotest, and use all the available features from both of them!

If you still have any doubt, check out the full documentation on KoinListener

Posted on by:

leocolman profile

Leonardo Colman

@leocolman

Kotlin enthusiast, enjoys open source as a hobby and is really into software testing!

Discussion

markdown guide
 

Hi , am new to testing and i work on android app and using koin for di ,
Should i use koinTest to inject my classes instead of mocking them to test behavior