Search code examples
kotlinktorkotest

How to test Ktor host routing?


Here is my setup:

fun Application.configure() {
    // ...
    routing {
        myApi()
    }
}
fun Route.myApi() {
    host("api.${environment?.config?.host}") {
        get("v1") { call.respondText("My api is here") }
    }
}

The configuration above should listen for requests on api subdomain on path /v1 wherever the application is deployed.

ktor {
  deployment {
    host = "my.test"
    port = 8080
  }

  application {
    modules = [my.configuration.KtorKt.configure]
  }
}

When I start this application and try to GET http://api.my.test:8080/v1 everything works as expected.

I am struggling with writing a test for this endpoint using Kotest and Ktor.

class ServerTest : FunSpec({
    test("my test") {
        testApplication {
            val response = client.get("http://api.my.test:8080/v1")
        }
    }
})

This resolves in the following error: Can not resolve request to http://api.my.test:8080. Main app runs at localhost:80, localhost:443 and external services are

How can I test this routing logic?


Solution

  • To solve your problem you can send the Host header manually. Here is an example:

    @Test
    fun test() = testApplication {
        environment {
            config = MapApplicationConfig(listOf("ktor.deployment.host" to "localhost"))
        }
        application {
            routing {
                host("api.${environment?.config?.host}") {
                    get("v1") { call.respondText("My api is here") }
                }
            }
        }
    
        val r = client.get("/v1") {
            header("host", "api.localhost")
        }
        assertEquals("My api is here", r.bodyAsText())
    }