how does one approach testing of a ktor applicatio...
# ktor
r
how does one approach testing of a ktor application with koin installed as a plugin and usage of
testApplication
? I got two rather basic needs: 1. injecting instances into my test code so I can do calls on them. 2. changing which instances I use in the cases where I use mocks. How is this done?
a
You can define a Ktor's module, which could accept a list of Koin modules to be able to configure the Koin plugin for different environments. Here is an example:
Copy code
fun Application.testModule(vararg modules: Module) {
    install(Koin) {
        slf4jLogger()
        modules(modules.toList())
    }

    val service by inject<MyService>()
    routing {
        get {
            call.respondText { service.getAll().joinToString(separator = ", ") }
        }
    }
}

class ProdService: MyService {
    override fun getAll(): List<String> {
        return listOf("a", "b", "c")
    }
}

interface MyService {
    fun getAll(): List<String>
}

val prodModule = module {
    single<MyService> { ProdService() }
}

fun main() {
    embeddedServer(Netty, watchPaths = listOf("classes"), port = 3333) {
        testModule(prodModule)
    }.start(wait = true)
}
Here is an example of the test where the service is overridden:
Copy code
@Test
fun test() = testApplication {
    environment {
        config = MapApplicationConfig()
    }
    application {
        testModule(module {
            single<MyService> { object : MyService {
                override fun getAll(): List<String> {
                    return listOf("dev1", "dev2", "dev3")
                }
            } }
        })
    }

    assertEquals("dev1, dev2, dev3", client.get("/").bodyAsText())
}