You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ktor结合Testcontainers测试时出现请求体序列化失败报错

报错根因

异常的核心触发原因是你手动实例化的Apache引擎HttpClient没有安装客户端侧的ContentNegotiation序列化插件:

  • 你仅在Ktor服务端的application配置块中调用了configureSerialization(),这个配置仅作用于服务端,不会自动同步给你手动创建的HTTP客户端
  • 未安装序列化插件的客户端无法自动将RegisterDTO这类自定义对象转换为HTTP请求要求的OutgoingContent格式,即使你手动设置了Content-Type: application/json请求头,也会抛出序列化失败异常
  • 额外问题:在testApplication测试块中手动创建外部HttpClient是不必要的,这类客户端不会走测试宿主的内部调用通道,执行效率更低,也容易漏配必要插件。
修复方案

方案1:使用测试宿主内置客户端(推荐)

testApplication块内置了预配置的测试客户端,无需手动引入Apache引擎,直接在创建客户端时加装序列化插件即可,修改后的测试代码段如下:

"register creator" - {
    testApplication {
        application {
            DbFactory.init(ds)
            configureSecurity()
            configureHTTP()
            configureMonitoring()
            configureSerialization()
            configureDependencyInjection()
            configureStatusPage()
            configureRouting()
        }

        // 替换原来手动new HttpClient的逻辑
        val client = createClient {
            install(io.ktor.client.plugins.contentnegotiation.ContentNegotiation) {
                json(Json {
                    isLenient = true
                    ignoreUnknownKeys = true
                    encodeDefaults = true
                })
            }
        }

        client.post("/api/v1/auth/register") {
            contentType(ContentType.Application.Json)
            setBody(RegisterDTO("some@gmail.com", "some", "some@sdfSDF"))
        }.apply {
            this.shouldHaveStatus(HttpStatusCode.OK)
        }
    }
}

该方案的客户端走测试宿主内部调用通道,不需要占用真实网络端口,测试执行速度更快。

方案2:自定义HttpClient补装插件

如果确实需要使用Apache引擎的自定义客户端,必须在客户端配置块中手动安装ContentNegotiation插件,修改代码如下:

val client = HttpClient(Apache) {
    install(io.ktor.client.plugins.contentnegotiation.ContentNegotiation) {
        json(Json {
            isLenient = true
            ignoreUnknownKeys = true
            encodeDefaults = true
        })
    }
}
额外注意事项
  • 确保RegisterDTO类添加了@kotlinx.serialization.Serializable注解,否则即使安装了序列化插件也无法正常完成对象序列化
  • 测试依赖可做如下精简,移除冗余项:
    • 删除ktor-server-tests-jvm,高版本Ktor仅保留ktor-server-test-host即可
    • 删除kotlin-test-junit,和已引入的kotlin-test功能重复
    • 删除org.testcontainers:junit-jupiter,你已经使用Kotest对应的Testcontainers扩展,不需要JUnit5专属的Testcontainers依赖

内容的提问来源于stack exchange,提问作者Victor Orlyk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 23:51:24