Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 283
vicaba Avatar asked Sep 03 '25 02:09

vicaba


1 Answers

Here you go, give this a read first - https://www.playframework.com/documentation/2.6.x/ScalaEssentialAction

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
        }
      }
    }
like image 195
saheb Avatar answered Sep 05 '25 00:09

saheb