我已经编写了一个实用工具类来帮助进行单元测试。一个函数,fakeRequest(),将处理请求,解析响应,验证JSON,并确保一般情况良好。然后它将(response, parsedJSON)
的元组返回给调用者。如果情况不佳,则返回failure
。
这一切都运行正常,但我无法弄清楚如何匹配返回的元组。
我想要的:
1.如果我得到(response, parsedJSON)
验证回复;
2.如果我得到failure
,则测试用例失败。
我的fakeRequest()
看起来像这样:
def fakeRequest[A, B](target: () => Call, request: A, response: B)(implicit f1: Format[A], f2: Format[B]) = {
route(FakeRequest(target()).withJsonBody(Json.toJson(request))) match {
case Some(response) => {
contentType(response) must beSome("application/json")
charset(response) must beSome("utf-8")
GPLog(s"fakeRequest: HTTP status ${status(response)}: JSON response: ${contentAsString(response)}")
val parsedJSON = Json.parse(contentAsString(response)).validate[B]
(response, parsedJSON)
}
case _ => failure
}
}
这就是我尝试匹配response
的方式。我已经尝试了几十种变体而且无法匹配response
上的:
fakeRequest(controllers.routes.GPInviteService.invite, test, GPInviteService.InviteResponse(true, None, None)) match {
case (response, JsSuccess(invite: GPInviteService.InviteResponse, _)) => { // Never matches
status(response) must beEqualTo(UNPROCESSABLE_ENTITY)
invite.inviteSent must beFalse
invite.error.get.code must beEqualTo(GPError.ValidationFailed.code)
}
case e: JsError => failure
...
这总是不起作用。但是,这真让我感到困惑,我可以返回响应状态代码,而不是response
对象本身。< / em>例如,如果我更改fakeRequest
:
def fakeRequest[A, B](target: () => Call, request: A, response: B)(implicit f1: Format[A], f2: Format[B]) = {
route(FakeRequest(target()).withJsonBody(Json.toJson(request))) match {
case Some(response) => {
// ...
(status(response), parsedJSON) // return status, not response?
}
case _ => failure
}
}
我可以对status
进行测试就好了,一切都按预期工作:
fakeRequest(controllers.routes.GPInviteService.invite, test, GPInviteService.InviteResponse(true, None, None)) match {
case (status, JsSuccess(response: GPInviteService.InviteResponse, _)) => { // Matches!
status must beEqualTo(UNPROCESSABLE_ENTITY)
response.inviteSent must beFalse
response.error.get.code must beEqualTo(GPError.ValidationFailed.code)
}
case e: JsError => failure
}
我很想理解为什么我可以匹配一个简单的状态代码,但我无法匹配更复杂的对象。
仅供参考,我甚至试过case (a, b) => println(a)
只看看会发生什么。返回response
时,它没有匹配。