Playframework test. FakeRequest sent with empty body always (scala)

I've been struggling several hours and every time I send a FakeRequest, it seems that the FakeApplication receives an empty body. However, if I try to run the play application and I send a normal request to localhost, everything works as expected, I receive the text I sent as a response.

enter image description here

Another test of the test that I have done is sending a custom response (not the same it receives) from the controller, like a string "a".

My test code looks like:

 val controller = app.injector.instanceOf(classOf[CreateRecordController]) val js = Json.obj() val result = controller.apply().apply( FakeRequest(POST, "/api/v1/record/") .withHeaders(Headers(CONTENT_TYPE -> "application/json")) .withJsonBody(js) ) val content = contentAsJson(result) info.apply(s"content was $content") 

The last statement prints: "content was" and an html page saying: "For request 'POST /api/v1/record/' [Invalid Json: No content to map due to end-of-input at [Source: akka.util.ByteIterator$ByteArrayIterator$$anon$1@5fdfe8cf; line: 1, column: 0]]" -> So the content is empty.

My action handler in the controller is:

 def apply: Action[JsValue] = Action.async(parse.json) { implicit request => Future.successful(BadRequest(request.body).withHeaders("Content-type" -> "application/json")) } 

Am I missing something?

Play version: 2.6.2

9

2 Answers

Here you go, give this a read first -

Controller

 def work = Action.async(parse.json) { implicit request => Future.successful(BadRequest(request.body).withHeaders((CONTENT_TYPE, "application/json"))) } 

Test

class ApplicationSpec extends PlaySpec with Results with GuiceOneAppPerTest with Injecting { "Application" should { "work" in { implicit lazy val materializer: Materializer = app.materializer val controller = new Application(inject[ControllerComponents]) val body = Json.obj() val result = call(controller.work(), FakeRequest(POST, "/work").withHeaders((CONTENT_TYPE, "application/json")).withJsonBody(body)) contentAsJson(result) mustBe body } } } 
1

It seems that if the content is passed to the FakeRequest at construction time it works as expected. What I've seen is that if I pass a JsValue as the body at construction time, the FakeRequest is of type FakeRequest[JsValue] which works fine. But if the method .withBodyAsJson is used, the type becomes FakeRequest[AnyContentAsJson]. It may be a bug.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like