我正在尝试为使用spray.io的同事制作API进行一些测试,我遇到了一些奇怪的行为。当请求因任何原因导致错误时,我们希望返回以下行的JSON值:
{"status":false,"message":"useful message here"}
在实际的浏览器中,这种情况很好。我已在Web浏览器中导航到未处理的路径,并获得所需的JSON值。所以,我想测试一下。现在,因为我是spray.io的新手,所以我从一个非常简单的测试开始:
"leave GET requests to root path unhandled" in {
Get() ~> myRoute ~> check {
handled must beFalse
}
}
这很好,没问题。由于这是我第一次使用spray.io,我查看了一些用于测试错误路由的示例测试,并将myRoute
与sealRoute()
打包在一起,这样我就可以检查响应而不会失败测试:
"leave GET requests to root path unhandled" in {
Get() ~> sealRoute(myRoute) ~> check {
handled must beTrue
}
}
这也很好。所以,在我解决JSON并验证各个值之前,我决定确保响应的文本可以用于此:
"leave GET requests to root path unhandled" in {
Get() ~> sealRoute(myRoute) ~> check {
responseAs[String] contains "false"
}
}
这是失败的。为了调查,我抛出了一行简单的代码来将responseAs[String]
的实际值记录到文件中,我得到了这个:
The requested resource could not be found.
谁能告诉我我做错了什么?我认为发生了下列情况之一:
responseAs[String]
做的不仅仅是采取确切的回复并将其还给我,在路上应用某种类型的过滤器我曾尝试专门针对类似问题搜索谷歌和堆栈溢出,但我要么没有提出正确的查询,要么大多数其他人都满足于拥有默认错误消息,并且除了检查之外没有尝试测试它们handled must beFalse
。
编辑 - 这是RejectionHandler的相关部分:
case MissingQueryParamRejection(paramName) :: _=>
respondWithMediaType(`application/json`) {
complete(BadRequest, toJson(Map("status" -> false, "message" -> s"Missing parameter $paramName, request denied")))
}
答案 0 :(得分:0)
好的,所以从这里和同事的见解,已经找到了问题:
基本上,自定义RejectionHandler
是在我们的自定义Actor
对象中定义的,并且它未在测试中进入范围。要解决此问题,请执行以下步骤:
RejectionHandler
的定义移动到单独文件中的自己的对象中(因为它必须执行自己的导入,导致“遇到不可恢复的循环解决导入”错误)(有趣的事实 - http://spray.io/documentation/1.2.2/spray-routing/key-concepts/rejections/#rejectionhandler似乎将RejectionHandler
演示为顶级对象,但你不能在Scala中拥有顶级隐式val,因此需要一个对象)