Reputation: 9428
I'm trying to create a function test for a Play 2 controller which takes multipart form data as input. There is no method currently in FakeRequest to support multipart form POST. What other ways to test this controller?
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
EDIT: This is the workaround I did to test 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();
}
Upvotes: 9
Views: 9368
Reputation: 2243
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);
Upvotes: 0
Reputation: 4823
Here is a solution with callAction() in Java to create the multipart/form-data content for a request. It works at least in Play 2.2.3. My content-type was application/zip. You might want to change this.
@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);
}
Upvotes: 2
Reputation: 5410
The easiest way to do this is to use Scala as follows:
val formData = Map(
"param-1" -> Seq("value-1"),
"param-2" -> Seq("value-2")
)
val result = routeAndCall(FakeRequest(POST, "/register").copy(body=formData))
This is assuming your controller method is of the form:
def register = Action(parse.tolerantFormUrlEncoded) { ... }
If you really must use Java, you don't have access to named parameters, so the 'copy' method above would have to be called in full. Also be careful to import the scala play.api.test.FakeRequest object, as the Java FakeRequest proxy doesn't have a copy method.
Upvotes: 2
Reputation: 1457
You should use callAction to use 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)
)
...
}
}
}
I use only Scala api for Play Framework 2 but I dont think you can test the multipart form using withFormUrlEncodedBody.
You can do in this way in 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))
...
}
}
}
I guess you can translate it to Java, I don't know how to code it in Java sorry.
P.D: Sorry for my English I'm still learning
Upvotes: 7