iT邦幫忙

2025 iThome 鐵人賽

DAY 24
0

今天來說 Ktor 自動化測試的部分

我們可以參考 https://openaidoc.org/zh-Hant/ktor/server-testing 這份文件

Ktor 的自動化測試使用的是 kotlin.test 這個框架

package com.example

import io.ktor.client.request.*
import io.ktor.http.*
import io.ktor.server.testing.*
import kotlin.test.Test
import kotlin.test.assertEquals

class ApplicationTest {
    @Test
    fun testRoot() =
        testApplication {
            application {
                module()
            }
            client.get("/").apply {
                assertEquals(HttpStatusCode.OK, status)
            }
        }
}

使用 testApplication() 建立測試用的 ApplicationTestBuilder 之後,

呼叫 application.module() 將對應的所有套件全部安裝好,包含路由也一併在這時候引入

安裝好之後就可以使用 ApplicationTestBuilder 內的 client 存取路由,

之後就可以對回傳內容作 assert 了。

如果要測試 POST 路徑也可以,我們可以使用 header()setBody() 設置 POST 請求的內容

@Test
fun testPost() = testApplication {
    application {
        module()
    }
    val response = client.post("/signup") {
        header(HttpHeaders.ContentType, ContentType.Application.FormUrlEncoded.toString())
        setBody(listOf("username" to "JetBrains", "email" to "example@jetbrains.com", "password" to "foobar", "confirmation" to "foobar").formUrlEncode())
    }
    assertEquals("The 'JetBrains' account is created", response.bodyAsText())
}

測試 Client

參考 https://openaidoc.org/zh-Hant/ktor/client-testing

假設我們有撰寫自定義的 Client 物件

@Serializable
data class IpResponse(val ip: String)

class ApiClient(engine: HttpClientEngine) {
    private val httpClient = HttpClient(engine) {
        install(ContentNegotiation) {
            json()
        }
    }

    suspend fun getIp(): IpResponse = httpClient.get("https://api.ipify.org/?format=json").body()
}

如果我們要測試 Client 連線狀況,而不實際的進行連線

我們可以使用 Ktor 的 ktor-client-mock

首先,我們先安裝測試用套件

testImplementation("io.ktor:ktor-client-mock:3.3.0")

然後測試內就可以使用了

class ApiClientTest {
    @Test
    fun sampleClientTest() {
        runBlocking {
            val mockEngine = MockEngine { request ->
                respond(
                    content = ByteReadChannel("""{"ip":"127.0.0.1"}"""),
                    status = HttpStatusCode.OK,
                    headers = headersOf(HttpHeaders.ContentType, "application/json")
                )
            }
            val apiClient = ApiClient(mockEngine)

            Assert.assertEquals("127.0.0.1", apiClient.getIp().ip)
        }
    }
}

由於 Ktor 核心的功能其實很精簡,針對 Ktor 本身的測試功能也非常精簡。

基本上只需要,也只能針對請求的內容和回應的內容進行判斷。其他的功能都隸屬於其他的框架或套件進行測試。

今天的部分就到這邊,我們明天見!


上一篇
Day 23:使用 ContentNegotiation 更換回傳格式
下一篇
Day 25:使用依賴注入時,怎麼在測試使用 Mock 元件
系列文
每天一點 Ktor 3.0:一個月學會 Kotlin 後端開發26
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言