最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

scala - Testing play framework controller with multipartdata - Stack Overflow

programmeradmin6浏览0评论

He guys,

I'm having issues with testing play controller that handles multipart form data. It expects text field and some files.

The controller uses temporary files def insert(): Action[MultipartFormData[TemporaryFile]].

It works fine on production but I'm trying to add tests and I can't figure out how to properly create test request.

I first tried:

        val formData: MultipartFormData[TemporaryFile] = MultipartFormData(
          dataParts = Map(
            "json" -> Seq(Json.stringify(Json.toJson(newCreateRequest(name = "library".some))))
          ),
          files = Seq(filePart),
          badParts = Seq.empty
        )
        
        val request = requestWithToken.withMultipartFormDataBody(formData)
        val result = controller.insert()(request) 

but it tells me boundary is missing so I tried explicitly setting content type header:

        FakeRequest()
            .withHeaders(
              "Content-Type" -> "multipart/form-data; boundary=----geckoformboundary689e6c2fb6158cafd1b47222ed5f83d3")

Now it doesn't make sense as MultipartFormData doesn't know boundary I used and I don't see any way to set it there. Anyway I'm getting bad request "Unexpected end of input".

I gave up with this approach and started creating raw request just to see if I get any other result.

        val boundary = "----geckoformboundary689e6c2fb6158cafd1b47222ed5f83d3"
        val body = """------geckoformboundary689e6c2fb6158cafd1b47222ed5f83d3
                     |Content-Disposition: form-data; name="json"
                     |
                     |{"name":"test"}
                     |------geckoformboundary689e6c2fb6158cafd1b47222ed5f83d3--
                     |""".stripMargin

And obviously creating request with content type and content length headers.

Nothing seems to work.

Since I added boundary I'm getting "Unexpected end of input".

I tried everything using ByteString instead of string body, using string body but replacing line endings.

I even tried running the test in a loop where iterator is being used to set content length in case the length is being calculated differently.

I obviously also tried with empty request (empty files or empty both text and file fields).

Nothing. I'm aways getting Unexpected end of input.

Has anyone had any luck with testing this stuff?

I'm running scala 2.13.16 and play 3.0.6.

He guys,

I'm having issues with testing play controller that handles multipart form data. It expects text field and some files.

The controller uses temporary files def insert(): Action[MultipartFormData[TemporaryFile]].

It works fine on production but I'm trying to add tests and I can't figure out how to properly create test request.

I first tried:

        val formData: MultipartFormData[TemporaryFile] = MultipartFormData(
          dataParts = Map(
            "json" -> Seq(Json.stringify(Json.toJson(newCreateRequest(name = "library".some))))
          ),
          files = Seq(filePart),
          badParts = Seq.empty
        )
        
        val request = requestWithToken.withMultipartFormDataBody(formData)
        val result = controller.insert()(request) 

but it tells me boundary is missing so I tried explicitly setting content type header:

        FakeRequest()
            .withHeaders(
              "Content-Type" -> "multipart/form-data; boundary=----geckoformboundary689e6c2fb6158cafd1b47222ed5f83d3")

Now it doesn't make sense as MultipartFormData doesn't know boundary I used and I don't see any way to set it there. Anyway I'm getting bad request "Unexpected end of input".

I gave up with this approach and started creating raw request just to see if I get any other result.

        val boundary = "----geckoformboundary689e6c2fb6158cafd1b47222ed5f83d3"
        val body = """------geckoformboundary689e6c2fb6158cafd1b47222ed5f83d3
                     |Content-Disposition: form-data; name="json"
                     |
                     |{"name":"test"}
                     |------geckoformboundary689e6c2fb6158cafd1b47222ed5f83d3--
                     |""".stripMargin

And obviously creating request with content type and content length headers.

Nothing seems to work.

Since I added boundary I'm getting "Unexpected end of input".

I tried everything using ByteString instead of string body, using string body but replacing line endings.

I even tried running the test in a loop where iterator is being used to set content length in case the length is being calculated differently.

I obviously also tried with empty request (empty files or empty both text and file fields).

Nothing. I'm aways getting Unexpected end of input.

Has anyone had any luck with testing this stuff?

I'm running scala 2.13.16 and play 3.0.6.

Share Improve this question edited Mar 20 at 18:16 Gaël J 15.6k5 gold badges22 silver badges45 bronze badges asked Mar 20 at 14:15 g-tg-t 1,53312 silver badges17 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

As per one of the test available in Play Framework codebase, you should be able to write something like the following:

      val boundary = "-----------------------------14568445977970839651285587160"
      val header =
        s"--$boundary\r\n" +
          "Content-Disposition: form-data; name=\"uploadedfile\"; filename=\"uploadedfile.txt\"\r\n" +
          "Content-Type: application/octet-stream\r\n" +
          "\r\n"
      val content = Array.ofDim[Byte](fileSize)
      val footer =
        "\r\n" +
          "\r\n" +
          s"--$boundary--\r\n"

      val body = Source(
        ByteString(header) ::
          ByteString(content) ::
          ByteString(footer) ::
          Nil
      )

      val bodySize = header.length + fileSize + footer.length

      val request = FakeRequest(
        method = "POST",
        uri = "/x",
        headers = FakeHeaders(
          Seq("Content-Type" -> s"multipart/form-data; boundary=$boundary", "Content-Length" -> bodySize.toString)
        ),
        body = body
      )
发布评论

评论列表(0)

  1. 暂无评论