自定义喷雾拒绝处理程序在测试中无法正常工作
Custom spray rejection handler not working properly in tests
我正在使用 spray
构建一些 JSON HTTP 服务,但我在测试 RejectionHandler
时遇到了一些问题。如果我启动应用程序 运行 命令 sbt run
并发出请求,RejectionHandler
按预期处理 MalformedRequestContentRejection
但当 运行 甚至在路线封闭的情况下进行测试。另一方面,MethodRejection
工作正常。 JSON 验证是使用 require
完成的
下一个例子基于spray-template
repository branch on_spray-can_1.3_scala-2.11
with a POST endpoint and the new tests. I've made a fork with the entire example here
注意使用 case clase
反序列化 JSONs,使用 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"
}
}
}
}
我错过了什么?
提前致谢!
您的 SomeReq
class 正在 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"
}
我正在使用 spray
构建一些 JSON HTTP 服务,但我在测试 RejectionHandler
时遇到了一些问题。如果我启动应用程序 运行 命令 sbt run
并发出请求,RejectionHandler
按预期处理 MalformedRequestContentRejection
但当 运行 甚至在路线封闭的情况下进行测试。另一方面,MethodRejection
工作正常。 JSON 验证是使用 require
下一个例子基于spray-template
repository branch on_spray-can_1.3_scala-2.11
with a POST endpoint and the new tests. I've made a fork with the entire example here
注意使用 case clase
反序列化 JSONs,使用 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"
}
}
}
}
我错过了什么?
提前致谢!
您的 SomeReq
class 正在 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"
}