After working for most of the day, I feel pretty close to deciding how to test a controller method that accepts file uploads from JUnit. My unit test code is as follows:
Map<String, String> postData = makePostMap(uploadForm); File file = new File("test/resources/shared/uploads/blank.csv"); TemporaryFile temporaryFile = new TemporaryFile(file); MultipartFormData.FilePart filePath = new MultipartFormData.FilePart( "file", "file.csv", new scala.Some<>("text/csv"), temporaryFile); List<MultipartFormData.FilePart> fileParts = Lists.newArrayList(filePath); scala.collection.immutable.Seq files = JavaConversions.asScalaBuffer(fileParts).toList(); Map<String, scala.collection.immutable.Seq<String>> postData2 = new HashMap<>(); for (String s : postData.keySet()) { postData2.put(s, JavaConversions.asScalaBuffer(Lists.newArrayList(postData.get(s))).toList()); } scala.collection.immutable.Map<String, scala.collection.immutable.Seq<String>> scalaMap = JavaConversions.mapAsScalaMap(postData2).toMap(Predef.<Tuple2<String, scala.collection.immutable.Seq<String>>>conforms()); MultipartFormData formData = new MultipartFormData(scalaMap, files, null, null); AnyContentAsMultipartFormData body = new AnyContentAsMultipartFormData(formData);
However, I get an exception (below) when FakeRequest is redirected to.
[error] Test controllers.ManageContactsTest.testUploadCsv failed: scala.MatchError: AnyContentAsMultipartFormData(MultipartFormData(Map(clearExisting -> List(false), survey -> List(11), bosMode -> List(false)),List(FilePart(file,file.csv,Some(text/csv),TemporaryFile(test/resources/shared/uploads/blank.csv))),null,null)) (of class play.api.mvc.AnyContentAsMultipartFormData), took 0.255 sec [error] at play.api.test.RouteInvokers$class.jRoute(Helpers.scala:255) [error] at play.api.test.Helpers$.jRoute(Helpers.scala:403) [error] at play.api.test.Helpers.jRoute(Helpers.scala) [error] at play.test.Helpers.route(Helpers.java:445) [error] at play.test.Helpers.route(Helpers.java:437) [error] at play.test.Helpers.route(Helpers.java:433) [error] at controllers.ManageContactsTest.testUploadCsv(ManageContactsTest.java:121) [error] ...
Immersed in the stack trace, I found the following scala match statement in the file: /Users/jcreason/bin/playframework-2.3.8/framework/src/play-test/src/main/scala/play/api/test/Helpers.scala:253
def jRoute[T](app: Application, r: FakeRequest[T]): Option[Future[Result]] = { (r.body: @unchecked) match { case body: AnyContentAsFormUrlEncoded => route(app, r, body) case body: AnyContentAsJson => route(app, r, body) case body: AnyContentAsXml => route(app, r, body) case body: AnyContentAsText => route(app, r, body) case body: AnyContentAsRaw => route(app, r, body) case body: AnyContentAsEmpty.type => route(app, r, body)
Since I go through AnyContentAsMultipartFormData , it throws this exception, since it is not handled by the match. Does anyone know how to get around this? Or could he point me in the direction of another solution to this question (besides the obvious answers, like selenium)?
For reference, I pulled some of this code from:
http://www.erol.si/2014/02/how-to-test-file-uploads-in-play-framework-java/