在一天的大部分时间工作之后,我觉得我已经相当接近于如何测试一个接受来自 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/