定制喷雾剔除处理程序在测试中无法正常工作

时间:2015-08-29 19:38:30

标签: scala akka spray specs2

我正在使用spray构建一些JSON HTTP服务,我在测试RejectionHandler时遇到了一些问题。如果我启动运行命令sbt run的应用程序并发出请求,RejectionHandler按预期处理MalformedRequestContentRejection但是在运行测试时我得到IllegalArgumentException路线密封。另一方面,MethodRejection工作正常。 JSON验证使用require

完成

下一个示例基于spray-template repository分支on_spray-can_1.3_scala-2.11,其中包含POST端点和新测试。我用完整的例子here

做了一个分叉

请注意使用case clase反序列化JSON,使用require方法进行验证以及声明隐式RejectionHandler

package com.example

import akka.actor.Actor
import spray.routing._
import spray.http._
import StatusCodes._
import MediaTypes._
import spray.httpx.SprayJsonSupport._

class MyServiceActor extends Actor with MyService {
  def actorRefFactory = context
  def receive = runRoute(myRoute)
}

case class SomeReq(field: String) {
  require(!field.isEmpty, "field can not be empty")
}
object SomeReq {
  import spray.json.DefaultJsonProtocol._
  implicit val newUserReqFormat = jsonFormat1(SomeReq.apply)
}

trait MyService extends HttpService {
  implicit val myRejectionHandler = RejectionHandler {
    case MethodRejection(supported) :: _ => complete(MethodNotAllowed, supported.value)
    case MalformedRequestContentRejection(message, cause) :: _ => complete(BadRequest, "requirement failed: field can not be empty")
  }
  val myRoute =
    pathEndOrSingleSlash {
      post {
        entity(as[SomeReq]) { req =>
          {
            complete(Created, req)
          }
        }
      }
    }
}

这是使用spray-testkit实施的测试。最后一个需要BadRequest,但测试失败并带有IllegarArgumentException

package com.example

import org.specs2.mutable.Specification
import spray.testkit.Specs2RouteTest
import spray.http._
import StatusCodes._
import spray.httpx.SprayJsonSupport._

class MyServiceSpec extends Specification with Specs2RouteTest with MyService {
  def actorRefFactory = system

  "MyService" should {
    "leave GET requests to other paths unhandled" in {
      Get("/kermit") ~> myRoute ~> check {
        handled must beFalse
      }
    }
    "return a MethodNotAllowed error for PUT requests to the root path" in {
      Put() ~> sealRoute(myRoute) ~> check {
        status should be(MethodNotAllowed)
        responseAs[String] === "POST"
      }
    }
    "return Created for POST requests to the root path" in {
      Post("/", new SomeReq("text")) ~> myRoute ~> check {
        status should be(Created)
        responseAs[SomeReq] === new SomeReq("text")
      }
    }
    /* Failed test. Throws IllegalArgumentException */
    "return BadRequest for POST requests to the root path without field" in {
      Post("/", new SomeReq("")) ~> sealRoute(myRoute) ~> check {
        status should be(BadRequest)
        responseAs[String] === "requirement failed: field can not be empty"
      }
    }
  }
}

我遗失了什么?

提前致谢!

1 个答案:

答案 0 :(得分:2)

您的SomeReq类正在Post("/", new SomeReq(""))请求构建器中急切地实例化,并且require实例化后会立即调用class方法。

为了解决这个问题,请尝试使用以下代码:

import spray.json.DefaultJsonProtocol._
Post("/", JsObject("field" → JsString(""))) ~> sealRoute(myRoute) ~> check {
  status should be(BadRequest)
  responseAs[String] === "requirement failed: field can not be empty"
}