💨
Ktor 2.0 の testApplication で client の共通処理を書く
最近 Ktor 2.0.2 にアップデートしたところ、今までテストで使用していたメソッドが非推奨になっていた。ガイドを見るとtestApplication
を使用したテストが記載されていた。
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.testing.*
import kotlin.test.*
class ApplicationTest {
@Test
fun testRoot() = testApplication {
val response = client.get("/")
assertEquals(HttpStatusCode.OK, response.status)
assertEquals("Hello, world!", response.bodyAsText())
}
}
このようにtestApplication
で定義されている client を使用して http request を実行する。client をカスタマイズする場合のサンプルも書いてあったのだが、各テストケースで毎回 client をカスタマイズをするのは微妙だと思ったので、テスト用の関数を作った。以下の関数を使用すると Authorization ヘッダにBearer token
という文字列が設定された状態で http request を実行する。作成したソースコードは github のリポジトリを参照。
fun customTest(
url: String,
httpMethod: HttpMethod,
body: Any? = null,
assertBlock: suspend (response: HttpResponse) -> Unit
) {
return runBlocking {
val testApp = TestApplication {
application {
configureRouting()
}
}
try {
val testClient = testApp.createClient {
install(DefaultRequest) {
header("Authorization", "Bearer token") // ちゃんとした jwt を生成して設定する
contentType(ContentType.Application.Json)
}
install(ContentNegotiation) {
jackson {
// jackson の設定を追記する
}
}
}
runBlocking {
val response = testClient.request(urlString = url) {
method = httpMethod
setBody(body)
}
assertBlock(response)
}
} finally {
testApp.stop()
}
}
}
レスポンスで Authorization header を返却する routing を定義し Bearer token
が返却されることを確認した。
fun Application.configureRouting() {
routing {
get("/") {
call.respondText("Hello World!")
}
get("/header_test") {
call.respondText(call.request.headers["Authorization"]!!)
}
}
}
class ApplicationTest {
@Test
fun testRoot() = testApplication {
application {
configureRouting()
}
client.get("/").apply {
assertEquals(HttpStatusCode.OK, status)
assertEquals("Hello World!", bodyAsText())
}
}
@Test
fun customTest() {
customTest(url = "/header_test", httpMethod = HttpMethod.Get) { response ->
response.apply {
assertEquals(HttpStatusCode.OK, status)
// Authorization ヘッダの中身が返却されることを確認
assertEquals("Bearer token", bodyAsText())
}
}
}
}
Discussion