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

withFormUrlEncodedBody を使用するには callAction を使用する必要があります

@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)
            )
            ...
         }
     }
}

私は Play Framework 2 用の Scala API のみを使用していますが、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

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);
}
于 2015-01-24T21:40:38.510 に答える
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 を使用する必要がある場合は、名前付きパラメーターにアクセスできないため、上記の「copy」メソッドを完全に呼び出す必要があります。Java FakeRequest プロキシには copy メソッドがないため、scala play.api.test.FakeRequest オブジェクトのインポートにも注意してください。

于 2012-06-17T10:09:45.057 に答える