K  D
K D

Reputation: 314

Akka Route TestKit could not unmarshall response as String

I have the following test:

 "fail if date is wrongly formatted" in {
    val endpoint = s"/api/prof?date=wrongdate"
    Get(endpoint) ~> check {
      status shouldBe StatusCodes.BadRequest
      val resp = responseAs[String]
      resp shouldBe "could not be parsed"
    }
 }

However, the test fails with the following:

Could not unmarshal response to type 'java.lang.String' for `responseAs` assertion: akka.http.scaladsl.unmarshalling.Unmarshaller$UnsupportedContentTypeException: Unsupported Content-Type [Some(text/plain; charset=UTF-8)], supported: application/json

Response was: HttpResponse(400 Bad Request,List(),HttpEntity.Strict(text/plain; charset=UTF-8,106 bytes total),HttpProtocol(HTTP/1.1))

How can I get the response body as a String?

Upvotes: 1

Views: 861

Answers (2)

Legionas
Legionas

Reputation: 31

Levi Ramsey, is right about the implicit unmarshaller for JSON, for text/plain(UTF-8) content-type you could extract the message by getting the ByteString source to avoid implicit ruining your tests.

class SomeAkkaTestSpec extends AnyWordSpec with should.Matchers with ScalaFutures with ScalatestRouteTest {

  "return 200 with message" in {
    val request = Get("/fetch/xxxxx")

    request ~> routes ~> check {
      status shouldBe StatusCodes.OK
      contentType shouldBe ContentTypes.`text/plain(UTF-8)`
      responseEntity.dataBytes
        .map(_.utf8String)
        .runWith(Sink.head)
        .futureValue shouldBe "Hello"
    }
  }
}

Upvotes: 3

Levi Ramsey
Levi Ramsey

Reputation: 20591

Presumably you have an implicit unmarshaller for JSON in scope, so that's getting picked up as the unmarshaller in your test.

Adding something like

implicit val responseBodyUnmarshaller =
  Unmarshaller.strict[HttpResponse, HttpEntity](_.entity)
    .andThen(Unmarshaller.stringUnmarshaller)

should address this.

Upvotes: 2

Related Questions