在Ktor中测试Post请求

时间:2017-12-31 06:55:00

标签: http kotlin ktor

Ktor(kotlin web框架)有一个非常棒的可测试模式,其中http请求可以包含在单元测试中。他们举了一个很好的例子来说明如何测试GET端点here, 但是我在使用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 个答案:

答案 0 :(得分:2)

好的愚蠢的错误,我会在这里发布以防万一这样可以避免浪费时间;) 单元测试实际上是在捕捉一个真正的问题(这就是我猜他们的意思) 在我的路由中,我正在使用:

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

然而,这只适用于'get'参数。邮政需要:

install(Routing) {
        post("/api/v2/processing") {
            val params = call.receive<ValuesMap>()
            ...
        }
}

答案 1 :(得分:1)

call.parameters也适用于帖子路线。

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

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

call.receive用于请求的正文。

答案 2 :(得分:0)

对于今天阅读这些内容的人,早在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())

答案 3 :(得分:0)

对于使用备用.apply来验证结果的用户,您可以在测试调用之前将主体放在前面

withTestApplication({ module(testing = true) }) {
            handleRequest(HttpMethod.Post, "/"){
                setBody(...)
            }.apply {
                assertEquals(HttpStatusCode.OK, response.status())
                assertEquals("HELLO WORLD!", response.content)
            }
        }