question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Testing Ktor application fails with "A Koin Application has already been started"

See original GitHub issue

I am trying to unit test a ktor application powered by koin, described as follows:

  • The gradle.properties:
ktor_version=1.2.2
kotlin_version=1.3.40
logback_version=1.2.1
  • The build.gradle’s dependencies:
dependencies {
    compile("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version")
    compile("io.ktor:ktor-server-netty:$ktor_version")
    compile("ch.qos.logback:logback-classic:$logback_version")
    compile("org.koin:koin-ktor:2.0.1")
    testCompile("io.ktor:ktor-server-tests:$ktor_version")
    testCompile("org.koin:koin-test:0.9.3")
}
  • The resources/application.conf:
ktor {
    deployment {
        port = 8080
    }
    application {
        modules = [com.example.MainApplicationKt.main]
    }
}
  • The com.example.MainApplication.kt:
package com.example

// imports...

interface HelloController {
    suspend fun onGetHello(call: ApplicationCall)
}

class DefaultHelloController() : HelloController {
    override suspend fun onGetHello(call: ApplicationCall) {
        call.respondText("Hello World!")
    }
}

fun main(args: Array<String>) {
    embeddedServer(Netty, commandLineEnvironment(args)).start()
}

fun Application.main() {
    install(DefaultHeaders)
    install(CallLogging)
    install(org.koin.ktor.ext.Koin) {
        modules(helloModule)
    }
    val helloController: HelloController by inject()
    routing {
        get("/hello") {
            helloController.onGetHello(call)
        }
    }
}
  • and finally the MainApplicationTest.kt:
class MainApplicationTest {

    private object MockHelloController : HelloController {
        override suspend fun onGetHello(call: ApplicationCall) {
            call.respondText("Mocked Hello World!")
        }
    }

    @Before
    fun setup() {
        val mockHelloModule = module {
            single<HelloController> { MockHelloController }
        }
        startKoin {
            listOf(mockHelloModule)
        }
    }

    @After
    fun teardown() {
        stopKoin()
    }

    @Test
    fun testRequestsOK() = withTestApplication(Application::main) {
        with(handleRequest(HttpMethod.Get, "/hello")) {
            assertEquals(HttpStatusCode.OK, response.status())
            assertEquals("Mocked Hello World!", response.content)
        }
    }
}

When running the unit test, I get the following exception:

org.koin.core.error.KoinAppAlreadyStartedException: A Koin Application has already been started

What is the proper way to setup my unit tests?

Thanks in advance, Regards, Romain

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:7 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
iRYO400commented, Jun 10, 2020

Oops, that was easier than I thought. Just add stopKoin() inside

    @After
    fun tearDown() {
        stopKoin()
    }
1reaction
bio007commented, Feb 1, 2020

I’m facing similar problem with robolectric. See this issue https://github.com/robolectric/robolectric/issues/3108

I think it’s a problem Koin is having some static variables remembering previous runs (tests). This way the tests are not isolated and something can go wrong…

Read more comments on GitHub >

github_iconTop Results From Across the Web

A Koin Application has already been started - ...
Implementing the abstract AutoCloseKoinTest class will automatically stop Koin after each test. Here's an example with Robolectric:
Read more >
Injecting in Tests
You need to Register the KoinTestExtension and provide your module configuration. After this is done you can either get or inject your components...
Read more >
Testing
Ktor provides a special testing engine that doesn't create a web server, doesn't bind to sockets, and doesn't make any real HTTP requests....
Read more >
Error with Koin DI in Ktor version 1.6.6+
When adding modules for dependency injection with Koin (using latest version 3.1.4) there is a weird bug in versions 1.6.6+. Here's my repo....
Read more >
Now I m getting The test application has already been built
The test application has already been built. Make sure you configure the application before accessing the client for the first time. ... I...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found