5

Ktor(kotlin Web 框架)有一个很棒的可测试模式,可以将 http 请求包装在单元测试中。他们给出了一个很好的例子来说明如何在这里测试 GET 端点,但是我在使用 http POST 时遇到了问题。

我试过这个,但帖子参数似乎没有添加到请求中:

    @Test
fun testSomePostThing() = withTestApplication(Application::myModule) {
    with(handleRequest(HttpMethod.Post, "/api/v2/processing") {
        addHeader("content-type", "application/x-www-form-urlencoded")
        addHeader("Accept", "application/json")
        body = "param1=cool7&param2=awesome4"
    }) {
        assertEquals(HttpStatusCode.OK, response.status())
        val resp = mapper.readValue<TriggerResponse>(response.content ?: "")
        assertEquals(TriggerResponse("cool7", "awesome4", true), resp)
    }
}

有人有想法么?

4

4 回答 4

3

对于那些使用备用.apply来验证结果的人,您可以在测试调用之前添加正文

withTestApplication({ module(testing = true) }) {
            handleRequest(HttpMethod.Post, "/"){
                setBody(...)
            }.apply {
                assertEquals(HttpStatusCode.OK, response.status())
                assertEquals("HELLO WORLD!", response.content)
            }
        }
于 2020-10-08T00:51:41.857 回答
2

好吧,愚蠢的错误,我会在这里发布它以防其他人浪费时间;)单元测试实际上是在解决一个真正的问题(我猜这就是他们的目的)在我使用的路由中:

install(Routing) {
        post("/api/v2/processing") {
            val params = call.parameters
            ...
        }
}

但是,这只适用于“获取”参数。发布参数需要:

install(Routing) {
        post("/api/v2/processing") {
            val params = call.receive<ValuesMap>()
            ...
        }
}
于 2017-12-31T13:59:08.750 回答
1

对于那些现在阅读它的人来说,早在 2018 年receiveParameters()就为此类案例添加了方法。您可以将其用作:

install(Routing) {
        post("/api/v2/processing") {
            val params = call.receiveParameters()
            println(params["param1"]) // Prints cool7
            ...
        }
}

另外值得注意的是,示例中的请求构造现在可以进一步改进:

// Use provided consts, not strings
addHeader(HttpHeaders.ContentType, ContentType.Application.FormUrlEncoded.toString())
// Convenient method instead of constructing string requests 
setBody(listOf("param1" to "cool7", "param2" to "awesome4").formUrlEncode())
于 2019-07-01T10:16:39.357 回答
1

call.parameters 也适用于发布路线。

get("api/{country}") {
    val country = call.parameters["country"]!!
    ...
}

这将为您提供 api 之后在 uri 中传递的任何内容。

call.receive 用于请求的正文。

于 2018-01-08T13:07:49.633 回答