1

I'm trying to set up some tests for an API made by a coworker with spray.io, and I'm encountering some odd behavior. When a request results in an error for any reason, we want to return a JSON value along the lines of:

{"status":false,"message":"useful message here"}

This happens just fine in the actual browser. I have navigated to an unhandled route in the web browser, and I get the desired JSON value. So, I want to test this. Now, since I'm new to spray.io, I started off with the very simple test:

"leave GET requests to root path unhandled" in {
  Get() ~> myRoute ~> check {
    handled must beFalse
  }
}

This went fine, no problems. Since it's my first time playing with spray.io, I looked at some of the sample tests for testing false routes, and wrapped myRoute with sealRoute() so I could check the response without failing tests:

"leave GET requests to root path unhandled" in {
  Get() ~> sealRoute(myRoute) ~> check {
    handled must beTrue
  }
}

This also works fine. So, I decided to just make sure the text of the response was usable with this, before I went to the trouble of parsing JSON and verifying individual values:

"leave GET requests to root path unhandled" in {
  Get() ~> sealRoute(myRoute) ~> check {
    responseAs[String] contains "false"
  }
}

This is failing. To investigate, I threw a simple line of code in to log the actual value of responseAs[String] to a file, and I got this:

The requested resource could not be found.

Can anyone tell me what I'm doing wrong? I'm thinking that one of the following is occurring:

  • responseAs[String] is doing more than taking the exact response and giving it back to me, applying some type of filter along the way
  • The framework itself is not fully evaluating the query, but rather making a mockup object for the test framework to evaluate, and therefore not executing the desired 'turn errors to json' methods that my co-worker has implemented

I have tried searching google and stack overflow specifically for similar issues, but I'm either not putting in the right queries, or most other people are content to have the default error messages and aren't trying to test them beyond checking handled must beFalse.

Edit - This is the relevant part of the RejectionHandler:

case MissingQueryParamRejection(paramName) :: _=>
  respondWithMediaType(`application/json`) {
    complete(BadRequest, toJson(Map("status" -> false, "message" -> s"Missing parameter $paramName, request denied")))
  }
4

1 回答 1

0

好的,从这里和同事那里得到洞察,问题已经找到:

基本上,自定义RejectionHandler是在我们的自定义Actor对象中定义的,并且它没有进入测试范围。为了解决这个问题,采取了以下步骤:

  • 将自定义的定义移动RejectionHandler到单独文件中的自己的对象中(因为它必须进行自己的导入,因此导致“遇到不可恢复的循环解析导入”错误)
  • 将此新对象导入到原始文件和测试规范中。

(有趣的事实 - http://spray.io/documentation/1.2.2/spray-routing/key-concepts/rejections/#rejectionhandler似乎证明了RejectionHandler作为顶级对象,但你不能拥有顶级隐含Scala 中的 vals,因此需要一个对象)

于 2014-12-17T19:36:19.803 回答