java - 使用 Java Play Framework 2.3.x 在 Controller 中上传单元测试文件

标签 java scala junit playframework playframework-2.3

在一天的大部分时间工作之后,我觉得我已经相当接近于如何测试一个接受来自 JUnit 的文件上传的 Controller 方法的解决方案。我的juint测试代码如下:

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);

// 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,它抛出了这个异常,因为它没有被匹配处理。有谁知道如何解决这个问题?或者可以指出一个不同的解决方案的方向(除了像 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<Source<ByteString, ?>> part = new FilePart<>("key", "fileName", "application/octet-stream",
                Source.empty());
        List<Part<Source<ByteString, ?>>> 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")) ;

关于java - 使用 Java Play Framework 2.3.x 在 Controller 中上传单元测试文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32791562/

相关文章:

Java从csv读取并显示在jTable上

java - 如何对 void 方法进行 Junit 测试

java - 在 Spring MVC Controller 中测试 POST 方法的正确方法

java - 为什么 Mac 上的 java midi 合成器停止播放音符

java - 如何从sun bug数据库中的内部版本号查找jdk版本

scala - 无法使用 Spark 流应用程序查看 Twitter 流

scala-将自类型注释类传递给子对象

java - hibernate validator : Violation Message Language

java - 多个用户的 Spring websocket 安全性

scala - 在 Scala 中创建队列