简体   繁体   中英

Spray unmarshalling generic type

I'm using spray-client to generate http requests to my server in e2e tests. I also use specs2 to test for the desired response from the server. And everything works fine. I've built some custom specs2 matchers to simplify my test code. My test looks like this:

val response = get(<server_endpoint_url>)

response must beSuccessfulWith(content = expected_data)

I have a trait that somewhat simplifies the usage of spray in the test itself:

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))
}

I also have a trait where I define the custom matchers I use in the test:

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 
      } 
}

My problem starts when I try to make the matchers more general and support any Scala type for instance. I define something like this:

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

But then I get the following error message:

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 } }

Is there anything simple that I'm missing?

Thanks!

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

You need to add a constraint to your T parameter

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM