在 FakeRequest 中使用 MultipartFormData 播放框架测试 [英] Play Framework Testing using MultipartFormData in a FakeRequest

查看:31
本文介绍了在 FakeRequest 中使用 MultipartFormData 播放框架测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在为 May Play Framework 2.2.x 应用程序编写一些 Specs2 测试,该应用程序接受 MultipartFormData 提交作为其功能的一部分.

I am currently in the process of writing some Specs2 tests for may Play Framework 2.2.x application which accepts MultipartFormData submissions as part of it's function.

我已经使用以下形式成功地编写了其他包含文本和 JSON 正文的测试:

I have successfully written other tests with text and JSON bodies using the following form:

"respond to POST JSON with description field present" in {
  running(FakeApplication()) {
    val response = route(FakeRequest(POST, "/submission.json").withJsonBody(toJson(Map("content" -> toJson("test-content"), "description" -> toJson("test-description"))))).get
    status(response) must equalTo(OK)
    contentType(response) must beSome.which(_ == "application/json")
    contentAsString(response) must contain(""""description":"test-description"""")
    contentAsString(response) must contain(""""content":"test-content"""")
  }
}

但是,当我使用 .withMultipartFormData 方法时,我收到以下错误:

However, when I use the .withMultipartFormData method I get the following errors:

Cannot write an instance of play.api.mvc.AnyContentAsMultipartFormData to HTTP response. Try to define a Writeable[play.api.mvc.AnyContentAsMultipartFormData]
val response = route(FakeRequest(PUT,"/submission.json/1/files").withMultipartFormDataBody(data)).get
                    ^

我一直试图调试的 MultipartFormData 测试的形式如下:

The MultipartFormData test I have been attempting to debug is of the form:

"respond to file PUT form with details not specififed" in {
  running(FakeApplication()) {
     val basePath:String = Play.application.path.getCanonicalPath();
     val data:MultipartFormData[TemporaryFile] = MultipartFormData(Map[String,Seq[String]](),
                                    List(
                                        FilePart("file_upload","",Some("Content-Type: multipart/form-data"),TemporaryFile(new java.io.File(basePath + "/test-data/testUpload.jpg")))
                                    ), 
                                    List(), 
                                    List())


     val response = route(FakeRequest(PUT,"/submission.json/1/files").withMultipartFormDataBody(data)).get
     status(response) must equalTo(CREATED)
 }
}

查看 FakeRequest 类相关版本的 Play Framework 文档我看不到太多可以帮助我追查问题:play.api.test.FakeRequest

Looking at the Play Framework documentation for the relevant version of the FakeRequest class I can't see too much to help me trace down the problem: play.api.test.FakeRequest

就此事的其他文档而言,Play Framework 网站和 Google 似乎相当缺乏.

And in terms of other documentation on the matter it seems the Play Framework website and Google are rather lacking.

我尝试了以下替代方法来尝试测试我的 MultipartFormData 代码:

I have tried the following alternative means of attempting to test my MultipartFormData code:

  • Writing a test case for file uploads in Play 2.1 and Scala
  • Test MultipartFormData in Play 2.0 FakeRequest
  • How do I test multipart form data requests for file uploads in Play Framework 2.0 using Java? (Translating to Scala code first).

但是,我也没有使用任何这些方法取得任何成功.

However, I have not had any success with any of these approaches either.

推荐答案

而不是在 FakeApplication 中进行测试,后者速度很慢并且(根据我的经验)在并行运行测试时容易出错,我一直在单元测试我的多部分表单上传处理程序,如下所示:

Rather than testing in a FakeApplication which is slow and (in my experience) can be error-prone when tests are running in parallel, I've been unit testing my Multipart form upload handlers like this:

  1. 从控制器中的实际上传处理中分离出 Play 线路;例如:

def handleUpload = Action(parse.multipartFormData) { implicit request =>
  doUpload(request)
}

def doUpload(request:Request[MultipartFormData[TemporaryFile]]) = {
  ...
}

(其中handleUpload 是routes 文件中处理POST 的方法)

(Where handleUpload is the method in your routes file that handles the POST)

现在您有了一个更容易获得的端点,您可以模拟您的服务层以适当响应好/坏请求,并将模拟服务注入您的控制器正在测试中(我不会在这里展示,有一百万种不同的方法可以做到这一点)

Now you've got an endpoint that's easier to get at, you can mock out your service layer to respond appropriately to good/bad requests, and inject the mock service into your controller under test (I won't show that here, there are a million different ways to do that)

现在模拟一个多部分请求,它将到达您的 doUpload 方法:

Now mock out a multipart request that will arrive at your doUpload method:

val request= mock[Request[MultipartFormData[TemporaryFile]]]
val tempFile = TemporaryFile("do_upload","spec")
val fileName = "testFile.txt"
val part = FilePart("key: String", fileName, None, tempFile)
val files = Seq[FilePart[TemporaryFile]](part)
val multipartBody = MultipartFormData(Map[String, Seq[String]](), files, Seq[BadPart](), Seq[MissingFilePart]())
request.body returns multipartBody 

  • 最后,您可以调用您的 doUpload 方法并验证功能:

    val result = controller.doUpload(request)
    status(result) must beEqualTo(201)
    

  • 通过这样的测试,您可以快速轻松地测试 Controller 中的所有错误处理路径(毕竟这可能是您想要做的),而无需额外开销启动整个应用程序.

    By testing like this, you can quickly and easily test all the error-handling paths in your Controller (which is probably what you're trying to do after all) without the overhead of needing to start the entire application.

    这篇关于在 FakeRequest 中使用 MultipartFormData 播放框架测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆