xenomachina
10/17/2024, 3:31 AMTestApplicationCall instances. They do something like this to create them:
val environment = createTestEnvironment { }
val application = Application(environment)
val call = TestApplicationCall(
application = application,
coroutineContext = coroutineContext
)
call.request.addHeader("X-Zaphod-Heads", "2")
// test code that uses the `ApplicationCall` goes here
After upgrading to 3.0.0, this code no longer works. We can't create an Application using Application(environment), and TestApplicationCall needs an Application.
The tests themselves actually just need ApplicationCall instances. The only thing TestApplicationCall has that we use that isn't also in ApplicationCall is request.addHeader (ie: TestApplicationReqest.addHeader on the request property.)
What's the right way to do this with ktor 3.0.0?Aleksei Tirman [JB]
10/17/2024, 8:08 AMtestApplication method or the ApplicationTestBuilder (https://ktor.io/docs/server-testing.html). Here is an example:
@Test
fun test() = runTest {
val builder = ApplicationTestBuilder().apply {
application {
routing {
get("/") {
call.response.header("custom", "value")
call.respond(HttpStatusCode.OK)
}
}
}
}
val response = builder.client.get("/")
assertEquals(response.headers["custom"], "value")
}xenomachina
10/17/2024, 6:58 PMxenomachina
10/17/2024, 6:59 PMfun callLogFormatter(
call: ApplicationCall,
clock: () -> Long
): String {
...
}
...
install(CallLogging) {
...
val clock = ::getTimeMillis
clock(clock)
format { call -> callLogFormatter(call, clock) }xenomachina
10/17/2024, 7:01 PMcallLogFormatter that:
1. create an ApplicationCall with various request properties (method, headers, path, etc.), response properties (eg: status code) and attributes (eg: CallStartTime)
2. pass the call to callLogFormatter
3. assert that the result of callLogFormatter is what we expect
With ktor 2.x we just directly created a TestApplicationCall, which made it fairly easy to construct an ApplicationCall we could pass to callLogFormatter without having to go through routing or other complications.
How can we do that with ktor 3.0.0?Aleksei Tirman [JB]
10/18/2024, 10:52 AMtestApplication API doesn't allow creating a separate ApplicationCall object. You can use the following code to test the callLogFormatter :
@Test
fun test() = testApplication {
routing {
get {
call.response.header("custom", "value")
callLogFormatter(call) {
123
}
// Make assertion
}
}
client.get("/")
}Aleksei Tirman [JB]
10/18/2024, 12:07 PMOsip Fatkullin
10/18/2024, 1:04 PMApplication :
@Test
fun test() = testApplication {
lateinit var application: Application
application { application = this }
startApplication()
val call = TestApplicationCall(
application = application,
coroutineContext = coroutineContext
)
}xenomachina
10/18/2024, 10:26 PMtestApplication? That is, instead of:
get { /* response setup and assertions */ }
is there an alternative to get that routes all HTTP methods?