使用Java Play Framework 2.3.x在控制器中unit testing文件上载

在大部分时间工作后,我觉得我非常接近如何测试接受来自JUnit的文件上传的控制器方法的解决方案。 我的juint测试代码如下:

Map 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 fileParts = Lists.newArrayList(filePath); scala.collection.immutable.Seq files = JavaConversions.asScalaBuffer(fileParts).toList(); Map<String, scala.collection.immutable.Seq> 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> scalaMap = JavaConversions.mapAsScalaMap(postData2).toMap(Predef.<Tuple2<String, scala.collection.immutable.Seq>>conforms()); MultipartFormData formData = new MultipartFormData(scalaMap, files, null, null); AnyContentAsMultipartFormData body = new AnyContentAsMultipartFormData(formData); // run login(employee); String url = routes.ManageContacts.uploadCsv().url(); FakeRequest fakeRequest = new FakeRequest(POST, url).withBody(body); fakeRequest = getAuthenticatedRequest(fakeRequest, employee); result = route(fakeRequest); assertThat(status(result)).isEqualTo(OK) 

但是,当FakeRequest被路由到时,我得到一个例外(下面)。

 [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] ... 

深入到堆栈跟踪中,我在文件中找到以下scala匹配语句: /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) //case _ => MatchError is thrown } } 

由于我正在通过AnyContentAsMultipartFormData ,它会抛出此exception,因为匹配不会处理它。 有谁知道怎么解决这个问题? 或者可以指出我对此的不同解决方案的方向(除了明显的答案,就像selenium)?

作为参考,我从以下代码中提取了一些代码:

http://www.erol.si/2014/02/how-to-test-file-uploads-in-play-framework-java/

此代码可能很有用:

 import static play.test.Helpers.*; import static org.junit.Assert.*; import java.util.*; import org.junit.Test; import akka.stream.javadsl.Source; import akka.util.ByteString; import play.mvc.Http.MultipartFormData.*; import play.mvc.Http.RequestBuilder; import play.mvc.Result; import play.test.*; class UploadFileTest extends WithApplication { @Test public void uploadTest() { Part> part = new FilePart<>("key", "fileName", "application/octet-stream", Source.empty()); List>> data = Arrays.asList(part); RequestBuilder requestBuilder = fakeRequest(controllers.routes.UploadController.upload()).method(POST) .bodyMultipart(data, mat); Result result = route(app, requestBuilder); assertEquals(Helpers.OK, result.status()); } } 

如果要发送非空文件,
而不是Source.empty()使用FileIO.fromFile(new File("path/to/file")) ;