喷涂解组通用类型

时间:2015-08-25 14:53:44

标签: scala spray specs2 spray-json spray-client

我正在使用spray-client在e2e测试中为我的服务器生成http请求。我还使用specs2来测试服务器所需的响应。一切正常。 我已经构建了一些自定义specs2匹配器来简化我的测试代码。我的测试看起来像这样:

val response = get(<server_endpoint_url>)

response must beSuccessfulWith(content = expected_data)

我有一个特点,在某种程度上简化了测试中喷雾的使用:

trait SprayTestClientSupport {
    implicit val system = ActorSystem()
    import system.dispatcher // execution context for futures

    val pipeline: HttpRequest => Future[HttpResponse] = sendReceive

    def get(url: String): Future[HttpResponse] = pipeline(Get(url))
}

我还有一个特性,我在其中定义了我在测试中使用的自定义匹配器:

trait SprayTestClientSupport extends ShouldMatchers with SprayJsonSupport with DefaultJsonProtocol {
    def beSuccessfulWith(content: Seq[Int]): Matcher[Future[HttpResponse]] = 
      beSuccessful and haveBodyWith(content)

    def haveBodyWith(content: Seq[Int]): Matcher[Future[HttpResponse]] = 
      containTheSameElementsAs(content) ^^ { f: Future[HttpResponse] =>
        Await.result(f, await).entity.as[Seq[Int]].right.get
      }

    def beSuccessful: Matcher[Future[HttpResponse]] =
      ===(StatusCode.int2StatusCode(200)) ^^ { f: Future[HttpResponse] =>
        Await.result(f, await).status 
      } 
}

当我尝试使匹配器更通用并支持任何Scala类型时,我的问题就开始了。我定义了这样的东西:

def haveBodyWith[T: TypeTag](content: T): Matcher[Future[HttpResponse]] = 
  ===(content) ^^ { f: Future[HttpResponse] => 
    Await.result(f, await).entity.as[T].right.get
}

但后来我收到以下错误消息:

Error:(49, 86) could not find implicit value for parameter unmarshaller: spray.httpx.unmarshalling.Unmarshaller[T]
===(content) ^^ { (f: Future[HttpResponse]) => { Await.result(f, await).entity.as[T].right.get } }

我有什么简单的遗失吗?

谢谢!

P.S.
I use the following spray versions:
spray-client_2.10 -> 1.3.3
spray-can_2.10    -> 1.3.3
spray-http_2.10   -> 1.3.3
spray-httpx_2.10  -> 1.3.3
spray-util_2.10   -> 1.3.3
spray-json_2.10   -> 1.3.2

1 个答案:

答案 0 :(得分:3)

您需要在T参数

中添加约束
def haveBodyWith[T: TypeTag : Unmarshaller](content: T): Matcher[Future[HttpResponse]] = 
  ===(content) ^^ { f: Future[HttpResponse] => 
     Await.result(f, await).entity.as[T].right.get
}