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:
Split out the Play wiring from your actual upload handling in your controller; e.g.:
def handleUpload = Action(parse.multipartFormData) { implicit request => doUpload(request) } def doUpload(request:Request[MultipartFormData[TemporaryFile]]) = { ... }
(Where handleUpload is the method in your
routes
file that handles thePOST
)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)
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
And finally, you can call your
doUpload
method and verify functionality:val result = controller.doUpload(request) status(result) must beEqualTo(201)
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.