【问题标题】:Play Framework & Scala: Problems with FakeRequest & JSON POST in unit testPlay Framework 和 Scala:单元测试中的 FakeRequest 和 JSON POST 问题
【发布时间】:2013-11-10 20:07:24
【问题描述】:

我花了太多时间尝试调试以下问题,但我不确定问题出在哪里。

问题:得到400 Bad Request, Invalid Json 作为响应,但有以下异常:

com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input
 at [Source: [B@6ee503c9; line: 1, column: 1]
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164) ~[jackson-databind.jar:2.2.2]
    at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:2931) ~[jackson-databind.jar:2.2.2]
    at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:2846) ~[jackson-databind.jar:2.2.2]
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1569) ~[jackson-databind.jar:2.2.2]
    at play.api.libs.json.JacksonJson$.parseJsValue(JsValue.scala:480) ~[play-json_2.10.jar:2.2.0]
    at play.api.libs.json.Json$.parse(Json.scala:27) ~[play-json_2.10.jar:2.2.0]

要在我的控制器中测试的方法:

  def createArticle(id: String) =
      Action.async(parse.json) { implicit request =>
        (request.body \ "content").asOpt[String].map {
            ............
            ............
        }.getOrElse(BadRequest("Invalid request body"))
      }

对应的单元测试:

  "create article" in {
    running(FakeApplication()) {
      val postJson = Json.obj("content" -> "article content")

      val result = resource.createArticle(ARTICE_ID)(FakeRequest(POST, controllers.routes.ArticleResource.create(ARTICLE_ID).url).withJsonBody(postJson).withHeaders(CONTENT_TYPE -> "application/json").run

      status(result) must equalTo OK
    }
  }

我阅读了here 的讨论,但那里的任何建议都没有帮助。

【问题讨论】:

标签: json unit-testing scala playframework


【解决方案1】:

我也遇到过类似的问题,但到目前为止还没有解决(优雅地,无论如何......)。由于我的环境是 java 而不是 scala,所以我可以预感一下。我认为当您发送帖子时它可能是异步完成的(在您的 create article 方法中使用 Action.async),因此您可能需要等待测试代码结果,然后再尝试查看它是否正常。

【讨论】:

    【解决方案2】:

    我遇到了类似的问题,解决方案指向here。就我而言,这是因为我使用了两次response.asJson(),正如@jroper 所述

    考虑到 HTTP 响应的主体是一个流,而不是 你想在内存中缓冲的东西,然后它使 感觉访问身体两次(不管你是什么格式 不支持访问正文)。

    【讨论】:

      【解决方案3】:

      尝试在方法定义中实例化您的请求。

      这就是它对我的工作方式(例如使用带有 JSON 正文和结果为 JSON 的 POST):

      "process" should {
          "should be valid" in {
       val request = FakeRequest(POST, "/").withJsonBody(Json.parse("""      {  
           "id":1,
           "name":"prod 1",
           "price":55.55
        }"""))
      
        val result: Future[Result] = controller.process.apply(request)      
        val json = contentAsJson(result)            
      
        status(result) must be(CREATED)
        (json \ "id").as[Int] mustBe 1
      
      // .. more assertions and rest of code ...
      

      这里的代码处理一个 JsValue 并查询它的节点以检查返回的值是否与所需的模拟数据输出匹配

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-06-09
        • 2017-08-25
        • 1970-01-01
        • 1970-01-01
        • 2013-10-29
        • 2023-03-03
        • 1970-01-01
        相关资源
        最近更新 更多