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?