在 FakeRequest 中使用 MultipartFormData 播放框架测试 [英] Play Framework Testing using MultipartFormData in a FakeRequest
问题描述
我目前正在为 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:
- 编写测试在 Play 2.1 和 Scala 中上传文件的案例
- 在 Play 2.0 FakeRequest 中测试 MultipartFormData
- 如何使用 Java 在 Play Framework 2.0 中测试文件上传的多部分表单数据请求?(首先转换为 Scala 代码).
- 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:
从控制器中的实际上传处理中分离出 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屋!