我正在尝试测试使用自定义bodyparser和JSON验证器的play framework 2.5.10控制器:
class MessagingController {
def validateJson[A : Reads] = parse.json.validate(
_.validate[A].asEither.left.map(e => BadRequest(JsError.toJson(e)))
)
def createMessageThread() = Action(validateJson[InboundMessageThread]) { request =>
Ok("OK") }
}
当我对此运行一个简单的测试用例时,我收到一个错误:
For request 'POST /api/v1/messageThreads' [Invalid Json: No content to map due to
end-of-input at [Source: akka.util.ByteIterator$ByteArrayIterator$$anon$1@5693d1d2; line: 1, column: 0]]
测试是:
val fakeRequest = FakeRequest()
.withHeaders(HeaderNames.CONTENT_TYPE -> "application/json")
.withBody(Json.parse(
s"""
|{
| "participants": [
| {"id": $currentUserId, "isAdmin": false}
| ],
| "isGroupThread": false
|}
""".stripMargin))
val result = messagingController.createMessageThread()(fakeRequest).run()
status(result) mustBe OK
如果我将控制器的操作更改为Action
,然后验证控制器主体中的JSON,它就可以工作。我不想这样做,因为我的许多REST控制器需要解析JSON并使用validateJson[T]
减少样板。如果我使用curl提交相同的有效负载,代码也可以工作。
如何测试此控制器?
答案 0 :(得分:1)
以下类型的请求有效:
val request = FakeRequest()
.withHeaders(CONTENT_TYPE -> "application/json")
.withBody(Json.fromJson[Place](body).get)
答案 1 :(得分:0)
试试这个,希望这会有所帮助
val postRequest = FakeRequest(POST, "/route/to/hit").withJsonBody(Json.obj(
"participants" -> Json.arr(Json.obj("id" -> "currentUserId", "isAdmin" -> false)),
"isGroupThread" -> false
))
val result = await(messagingController.createMessageThread()(postRequest))
status(result) must be equalTo (FORBIDDEN)
答案 2 :(得分:0)
我建议不要使用JSON bodyparser调用Action,而是建议使用AnyContent
正文解析器调用ActionBuilder,然后从正文中调用Json.validate - 从那里,你得到堆栈跟踪并查看失败的原因:
class MessagingController {
def createMessageThread() = Action { request =>
request.json.validate[MessageThread] {
case JsError(e) =>
logger.error(s"Failure parsing because $e")
BadRequest(JsError.toJson(e))
case JsSuccess(e) =>
Ok("OK")
}
}
}