我正在尝试为Play 2控制器创建一个功能测试,它将多部分表单数据作为输入。 FakeRequest目前没有方法支持多部分表单POST。还有哪些其他方法可以测试这个控制器?
Map<String, Object> map = new HashMap<String, Object>();
map.put("param1", "test-1");
map.put("param2", "test-2");
map.put("file", file)
Result result = routeAndCall(fakeRequest(POST, "/register").withFormUrlEncodedBody(map));// NO SUCH METHOD
编辑: 这是我测试multipart的解决方法。
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://localhost:3333/blobupload");
FileBody imageFile = new FileBody(new File("test/resources/test-1.jpg"));
StringBody guid1 = null;
StringBody guid2 = null;
try {
guid1 = new StringBody("GUID-1");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("key1", imageFile);
reqEntity.addPart("key2", guid1);
httppost.setEntity(reqEntity);
HttpResponse response;
try {
response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
assertThat(response.getStatusLine().getStatusCode()).isEqualTo(200);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
答案 0 :(得分:7)
您应该使用callAction来使用withFormUrlEncodedBody
@Test
public void testMyAction() {
running(fakeApplication(), new Runnable() {
public void run() {
Map<String,String> data = new HashMap<String, Object>();
data.put("param1", "test-1");
data.put("param2", "test-2");
data.put("file", file);
Result result = callAction(
controllers.whatever.action(),
fakeRequest().withFormUrlEncodedBody(data)
)
...
}
}
}
我只使用Scala api用于Play Framework 2,但我认为你不能使用withFormUrlEncodedBody来测试多部分表单。
你可以在Scala中这样做:
import play.api.libs.Files._
import play.api.mvc.MultipartFormData._
class MyTestSpec extends Specification {
"mytest should bla bla bla" in {
running(FakeApplication(aditionalConfiguration = inMemoryDatabase())) {
val data = new MultipartFormData(Map(
("param1" -> Seq("test-1")),
("param2" -> Seq("test-2"))
), List(
FilePart("payload", "message", Some("Content-Type: multipart/form-data"), play.api.libs.Files.TemporaryFile(new java.io.File("/tmp/pepe.txt")))
), List(), List())
val Some(result) = routeAndCall(FakeRequest(POST, "/route/action", FakeHeaders(), data))
...
}
}
}
我想你可以将它翻译成Java,我不知道如何用Java编写代码抱歉。
P.D:对不起我的英语我还在学习
答案 1 :(得分:2)
最简单的方法是使用Scala,如下所示:
val formData = Map(
"param-1" -> Seq("value-1"),
"param-2" -> Seq("value-2")
)
val result = routeAndCall(FakeRequest(POST, "/register").copy(body=formData))
这假设您的控制器方法的格式为:
def register = Action(parse.tolerantFormUrlEncoded) { ... }
如果您真的必须使用Java,则无法访问命名参数,因此必须完全调用上面的“复制”方法。另外要小心导入scala play.api.test.FakeRequest对象,因为Java FakeRequest代理没有复制方法。
答案 2 :(得分:2)
这是一个Java中的callAction()解决方案,用于为请求创建multipart / form-data内容。它至少在Play 2.2.3中起作用。我的内容类型是application / zip。您可能想要更改此内容。
@Test
public void callImport() throws Exception {
File file = new File("test/yourfile.zip");
FilePart<TemporaryFile> part = new MultipartFormData.FilePart<>(
"file", "test/yourfile.zip",
Scala.Option("application/zip"), new TemporaryFile(file));
List<FilePart<TemporaryFile>> fileParts = new ArrayList<>();
fileParts.add(part);
scala.collection.immutable.List<FilePart<TemporaryFile>> files = scala.collection.JavaConversions
.asScalaBuffer(fileParts).toList();
MultipartFormData<TemporaryFile> formData = new MultipartFormData<TemporaryFile>(
null, files, null, null);
AnyContent anyContent = new AnyContentAsMultipartFormData(formData);
Result result = callAction(
controllers.routes.ref.ImportExport.import(),
fakeRequest().withAnyContent(anyContent,
"multipart/form-data", "POST"));
// Your Tests
assertThat(status(result)).isEqualTo(OK);
}
答案 3 :(得分:0)
Map<String, Object> data = new HashMap<String, Object>();
map.put("param1", "test-1");
map.put("param2", "test-2");
final Http.RequestBuilder request = Helpers.fakeRequest()
.method(POST)
.bodyForm(formData)
.uri("/register");
final Result result = route(app, request);