9

我正在尝试为 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

编辑:这是我为测试多部分所做的解决方法。

    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();
}
4

4 回答 4

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编码。

PD:对不起我的英语我还在学习

于 2012-06-07T14:28:35.800 回答
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 代理没有复制方法。

于 2012-06-17T10:09:45.057 回答
2

这是使用 Java 中的 callAction() 为请求创建多部分/表单数据内容的解决方案。它至少在 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);
}
于 2015-01-24T21:40:38.510 回答
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);
于 2017-09-11T13:36:26.940 回答