PlayFramework FakeRequest returns 400 错误
PlayFramework FakeRequest returns 400 error
在路线中:
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"}
但是测试returns400错误.
怎么了?
(命令行测试以简单易懂取胜)
这里发生的是 Play 根据 body 的类型设置请求的内容类型。您正在使用 string body 以便您设置的内容类型 header 稍后被 text/plain; charset=utf-8
.
覆盖
因为您明确地将 body 解析为 Json,如果内容类型不是 [=13],body 解析器将 return 错误请求 403 =] 或 application/json
.
在你的情况下最好的办法是使用 Json body,即:
"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
构造函数从调用中推断您的操作的方法和 URL,从而使其更简洁:
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
作为 body 解析器来完全跳过检查内容类型。
在路线中:
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"}
但是测试returns400错误.
怎么了?
(命令行测试以简单易懂取胜)
这里发生的是 Play 根据 body 的类型设置请求的内容类型。您正在使用 string body 以便您设置的内容类型 header 稍后被 text/plain; charset=utf-8
.
因为您明确地将 body 解析为 Json,如果内容类型不是 [=13],body 解析器将 return 错误请求 403 =] 或 application/json
.
在你的情况下最好的办法是使用 Json body,即:
"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
构造函数从调用中推断您的操作的方法和 URL,从而使其更简洁:
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
作为 body 解析器来完全跳过检查内容类型。