PlayFramework FakeRequest返回400错误

时间:2015-01-31 01:13:48

标签: scala playframework-2.3

在路线中:

POST        /login                  controllers.ApplicationCtrl.login()

在控制器中:

  def login = Action(parse.json) { implicit request => {

    val email = (request.body \ "email").as[String]
    val password = (request.body \ "password").as[String]

     Ok(Json.toJson(
       Map("status" -> "OK",
        "message" -> "%s created".format(email))
      ))
}

在测试中

 "login" in new WithApplication{

      val request = route( FakeRequest(
        Helpers.POST,
        controllers.routes.ApplicationCtrl.login.url,
        FakeHeaders(Seq(CONTENT_TYPE -> Seq("application/json"))),
        """ {"email" : "bob@mail.com", "password" : "secret"} """
      )).get

      status(request) must equalTo(OK)

    }

当我使用命令行测试时:

curl --header "Content-type: application/json" --request POST --data '{"email" : "bob@mail.com", "password" : "secret"}' http://localhost:9000/login

得到了理想的回应。

{"status":"OK","message":"bob@mail.com created"} 

但测试返回 400错误

怎么了?

(命令行测试通过简单性和可理解性获胜)

1 个答案:

答案 0 :(得分:5)

这里发生的是Play根据正文的类型设置请求的内容类型。您正在使用字符串正文,以便稍后由text/plain; charset=utf-8覆盖您设置的内容类型标题。

因为您将身体显式解析为Json,如果内容类型不是text/jsonapplication/json,则正文解析器将返回错误请求403。

在你的情况下,最好的办法是使用Json体,即:

"login" in new WithApplication {

  val request = route( FakeRequest(
    POST,
    controllers.portal.routes.Portal.test.url,
    FakeHeaders(Seq.empty),
    play.api.libs.json.Json.obj("email" -> "bob@mail.com", "password" -> "secret")
  )).get

  status(request) must equalTo(OK)
}

请注意,您可以让替代FakeRequest构造函数从调用中推断出您的操作的方法和网址,从而使其更加简洁:

val request = route(FakeRequest(controllers.portal.routes.Portal.test)
    .withBody(Json.obj("email" -> "bob@mail.com", "password" -> "secret"))).get

您可以用作body参数及其内容类型映射的数据类型:

  • JsValue - > application/json
  • NodeSeq - > text/xml
  • String - > text/plain
  • Map[String, Seq[String]] - > application/x-www-form-urlencoded
  • Array[Byte] - >没什么

还可以选择使用tolerantJson作为正文解析器来完全跳过检查内容类型。