【问题标题】:Testing Post requests in Ktor在 Ktor 中测试 Post 请求
【发布时间】:2018-06-10 22:58:54
【问题描述】:

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)
    }
}

有人有什么想法吗?

【问题讨论】:

    标签: http kotlin ktor


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

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

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

      【讨论】:

        【解决方案3】:

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

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

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

        call.receive 用于请求的正文。

        【讨论】:

          【解决方案4】:

          对于那些现在阅读它的人,早在 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())
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-03-26
            • 2017-10-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-07-25
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多