【问题标题】:Custom spray rejection handler not working properly in tests自定义喷雾拒绝处理程序在测试中无法正常工作
【发布时间】:2015-08-29 19:38:30
【问题描述】:

我正在使用 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"
      }
    }
  }
}

我错过了什么?

提前致谢!

【问题讨论】:

    标签: scala akka spray specs2


    【解决方案1】:

    您的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"
    }
    

    【讨论】:

    • 谢谢!像魅力一样工作。
    猜你喜欢
    • 1970-01-01
    • 2013-05-31
    • 2016-09-08
    • 2014-11-13
    • 1970-01-01
    • 2014-10-23
    • 2015-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多