如何在 Play 框架 v2.x 中不使用 withJsonBody 为 FakeRequest 发送 json 字符串 body?
How to send json string body for FakeRequest without using withJsonBody in Play framework v2.x?
我有 play 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
所以发送的 Content-Type
header 不是 application/json
尽管我已经将 header 设置为 application/json
。可能正因为如此,request.body.asJson
returns None.
有人知道如何解决这个问题吗?
注意:我知道我可以在 FakeRequest 上使用 .withJsonBody(Json.parse(jsonStr))
并且它会成功,但是通过这种方式我不能发送损坏或无效的 json 字符串作为负测试用例,因为 withJsonBody
接受 JsValue,其中 json 字符串必须先用 Json.parse
.
转换
默认情况下,Content-Type
header 被框架覆盖。 blog
中给出了解决方法
在你的情况下,这应该有效
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)
我有 play 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
所以发送的 Content-Type
header 不是 application/json
尽管我已经将 header 设置为 application/json
。可能正因为如此,request.body.asJson
returns None.
有人知道如何解决这个问题吗?
注意:我知道我可以在 FakeRequest 上使用 .withJsonBody(Json.parse(jsonStr))
并且它会成功,但是通过这种方式我不能发送损坏或无效的 json 字符串作为负测试用例,因为 withJsonBody
接受 JsValue,其中 json 字符串必须先用 Json.parse
.
默认情况下,Content-Type
header 被框架覆盖。 blog
在你的情况下,这应该有效
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)