如何测试使用自定义 bodyparser 的播放框架控制器?
How to test a play framework controller that uses a custom bodyparser?
我正在尝试测试使用自定义 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@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 提交相同的负载,该代码也有效。
如何测试这个控制器?
尝试一下,希望对您有所帮助
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)
与其使用 JSON 主体解析器调用 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")
}
}
}
以下类型的请求有效:
val request = FakeRequest()
.withHeaders(CONTENT_TYPE -> "application/json")
.withBody(Json.fromJson[Place](body).get)
我正在尝试测试使用自定义 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@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 提交相同的负载,该代码也有效。
如何测试这个控制器?
尝试一下,希望对您有所帮助
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)
与其使用 JSON 主体解析器调用 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")
}
}
}
以下类型的请求有效:
val request = FakeRequest()
.withHeaders(CONTENT_TYPE -> "application/json")
.withBody(Json.fromJson[Place](body).get)