2012-06-05 34 views
9

我正在嘗試爲採用多部分表單數據作爲輸入的Play 2控制器創建功能測試。目前FakeRequest中沒有方法支持多部分表單POST。測試此控制器的其他方法有哪些?在Play 2.0中測試MultipartFormData FakeRequest

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

回答

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來播放框架2,但我不認爲你可以使用withFormUrlEncodedBody測試多形式。

您可以通過這種方式在斯卡拉做:

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:對不起,我的英語我還在學習

+0

爲什麼callAction需要withFormUrlEncodeBody? routeAndCall也應該工作。 routeAndCall(fakeRequest(POST,「/route").withFormUrlEncodedBody(map)); – angelokh

+0

Mutlipartformdata可能適用於scala和你的方法。但是,對於Java,withFormUrlEncodedBody不允許在Object類型中使用值的映射。 – angelokh

+0

我不知道爲什麼callAction需要Java風格,但似乎只能用callAction調用fakeRequest()。withFormUrlEncodeBody,無論如何,我對Java語言瞭解不多,所以我可能完全錯誤。我不認爲你需要使用withFormUrlEncodedBody來測試你的多部分,你應該只建立正確的POST請求。 – DamnWidget

2

要做到這一點,最簡單的方法是使用斯卡拉如下:

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代理沒有複製方法。

+0

可以在formData中允許文件嗎? – angelokh

2

以下是Java中的callAction()方法,用於爲請求創建多部分/表單數據內容。它至少在Play 2.2.3中起作用。我的內容類型是應用程序/郵編。你可能想改變這一點。

@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); 
} 
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); 
相關問題