如何在不使用 Play 框架 v2.x 中的 JsonBody 的情况下为 FakeRequest 发送 json 字符



我玩过Scala v2.3应用程序。我正在尝试通过发送带有 FakeRequest 的 json 字符串来创建控制器测试,如下所示:

class ApplicationSpec extends Specification {
  "Application" should {
    "Create Bob Test" in new WithApplication {
      val jsonStr = """{"text": "hi bob"}"""
      val result = route(FakeRequest(POST, "/bob")
        .withHeaders("Content-Type" -> "application/json")
        .withBody(jsonStr)
      ).get
      status(result) === OK
    }
  }
}

控制器:

object Application extends Controller {
  def bob = Action.async { request =>
    println("request.headers: " + request.headers)
    println("request.body: " + request.body)
    println("request.body.asJson: " + request.body.asJson)
    request.body.asJson.map { json =>
      // do something with the json
      Future.successful(Ok)
    }.getOrElse(Future.successful(BadRequest))
  }
}

当我运行测试时,它失败了,这就是打印的内容:

request.headers: ArrayBuffer((Content-Type,List(text/plain; charset=utf-8)))
request.body: AnyContentAsText({"text": "hi bob"})
request.body.asJson: None

因此,尽管我已将标头设置为application/json,但发送的Content-Type标头并不application/json。可能正因为如此,request.body.asJson返回 None。

有人知道如何解决这个问题吗?

注意:我知道我可以在 FakeRequest 上使用 .withJsonBody(Json.parse(jsonStr)) 并且它会成功,但通过这种方式,我无法为负测试用例发送损坏或无效的 json 字符串,因为withJsonBody接受 JsValue,必须首先使用 Json.parse 转换 json 字符串。

默认情况下,Content-Type 标头被框架覆盖。博客中给出了解决方法

在您的情况下,这应该有效

route(FakeRequest(POST, "/bob", FakeHeaders(Seq(CONTENT_TYPE->Seq("application/json"))), jsonStr))(Writeable(_.getBytes, None)).get

对于多个测试,可以在开始时为writable创建一个隐式,并且不需要在每个测试中都传递它:

implicit val wString: Writeable[String] = Writeable(_.getBytes, None)

相关内容

最新更新