fel*_*xgb 8 scala playframework
我正在尝试测试一个尝试解析请求中发送的JSON的控制器方法:
def addRoomToProfileForTime = Action.async(parse.json[AddRoomToProfileForTimeRequest]) { request =>
profileService.addRoomToProfileForTime(request.body.roomId, request.body.profileId, request.body.timeRange).value.map {
case Xor.Right(_) => Ok
case Xor.Left(err) => BadRequest(Json.toJson(err))
}
}
Run Code Online (Sandbox Code Playgroud)
这是表示请求的案例类:
final case class AddRoomToProfileForTimeRequest(
roomId: Int,
profileId: Int,
timeRange: TimeRange
)
implicit val addRoomToProfileForTimeRequestFormat:Format[AddRoomToProfileForTimeRequest] = Json.format
Run Code Online (Sandbox Code Playgroud)
这个代码按预期工作,我发出这样的请求:
curl -H "Content-Type: application/json" -X POST -d '{"roomId":3,"profileId":1,"timeRange":{"id":1,"fromTime":"2000-01-01T01:01","toTime":"2000-01-01T02:01"}}' http://localhost:9000/api/profiles/addRoomToProfileForTime
Run Code Online (Sandbox Code Playgroud)
但我正在尝试为这种方法编写一个测试(注意我使用macwire进行依赖注入,因此不能使用WithApplication
:
"add a room to profile for time" in new TestContext {
val roomId = 1
val profileId = 1
val from = "2000-01-01T01:01"
val to = "2000-01-01T02:01"
val requestJson = Json.obj(
"roomId" -> roomId,
"profileId" -> profileId,
"timeRange" -> Json.obj(
"id" -> 1,
"fromTime" -> from,
"toTime" -> to
)
)
implicit val system = ActorSystem()
implicit val materializer = ActorMaterializer()
val fakeReq = FakeRequest(Helpers.POST, "api/profiles/addRoomToProfileForTime")
.withHeaders(CONTENT_TYPE -> "application/json")
.withJsonBody(requestJson)
val result = profileController.addRoomToProfileForTime()(fakeReq).run
val content = contentAsString(result)
println(content)
status(result) must equalTo(OK)
}
Run Code Online (Sandbox Code Playgroud)
但是,此测试因Play中的错误请求而失败:
<body>
<h1>Bad Request</h1>
<p id="detail">
For request 'POST api/profiles/addRoomToProfileForTime' [Invalid Json: No content to map due to end-of-input at [Source: akka.util.ByteIterator$ByteArrayIterator$$anon$1@37d14073; line: 1, column: 0]]
</p>
</body>
Run Code Online (Sandbox Code Playgroud)
如果我解析JSON,request.body.asJson
方法的行为符合预期.它只使用上面的body解析器方法,我得到了这个错误.
小智 18
简短的回答是:在您FakeRequest
的控制器测试中使用该withBody
方法而不是withJsonBody
.
我也有这个问题,我尴尬地花了好几个小时,直到我弄清楚了.长答案是FakeRequest
的withJsonBody
返回FakeRequest[AnyContentAsJson]
,由于控制器期待一个JsValue
(没有的AnyContentAsJson
),当你调用apply()
你的行动就无法匹配这个应用方法,这是你想要的:
def apply(request: Request[A]): Future[Result]
Run Code Online (Sandbox Code Playgroud)
而不是打这个申请方式:
def apply(rh: RequestHeader): Accumulator[ByteString, Result]
Run Code Online (Sandbox Code Playgroud)
因此,既然您没有将任何字节传递给累加器,则会收到您收到的意外end-of-input
错误消息.