喷雾解组泛型
Spray unmarshalling generic type
我在 e2e 测试中使用 spray-client 向我的服务器生成 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
您需要为 T
参数添加约束条件
def haveBodyWith[T: TypeTag : Unmarshaller](content: T): Matcher[Future[HttpResponse]] =
===(content) ^^ { f: Future[HttpResponse] =>
Await.result(f, await).entity.as[T].right.get
}
我在 e2e 测试中使用 spray-client 向我的服务器生成 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
您需要为 T
参数添加约束条件
def haveBodyWith[T: TypeTag : Unmarshaller](content: T): Matcher[Future[HttpResponse]] =
===(content) ^^ { f: Future[HttpResponse] =>
Await.result(f, await).entity.as[T].right.get
}