2012-06-05 4 views
9

Ich versuche einen Funktionstest für einen Play 2 Controller zu erstellen, der mehrteilige Formulardaten als Eingabe akzeptiert. Es gibt derzeit keine Methode in FakeRequest, um mehrteiliges Formular-POST zu unterstützen. Welche anderen Möglichkeiten, diesen Controller zu testen?MultipartFormData in Play 2.0 testen 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 

EDIT: Dies ist die Abhilfe, die ich tat mehrt zu testen.

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

Antwort

7

sollten Sie verwenden callaction withFormUrlEncodedBody zu verwenden

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

Ich verwende nur Scala api für Play Framework 2, aber ich glaube nicht, dass Sie die mehrteiliger Form withFormUrlEncodedBody mit testen.

Sie können in Scala auf diese Weise tun:

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

Ich denke, man es auf Java übersetzen kann, weiß ich nicht, wie es leider in Java codieren.

PD: Sorry für mein Englisch Ich bin immer noch lernen

+0

Warum callaction für withFormUrlEncodeBody erforderlich ist? routeAndCall sollte ebenfalls funktionieren. routeAndCall (fakeRequest (POST, "/route").withFormUrlEncodedBody (map)); – angelokh

+0

Mutlipartformdata könnte für scala with you-Methode funktionieren. Für java würde withFormUrlEncodedBody jedoch keine Map mit Wert im Objekttyp zulassen. – angelokh

+0

Ich weiß nicht, warum callAction auf Java-Flavor benötigt wird, aber es scheint, als ob man nur fakeRequest() aufrufen kann. WithFormUrlEncodeBody mit callAction, ich weiß sowieso nicht viel über Java, also kann ich völlig falsch liegen. Ich denke nicht, dass Sie mitFormUrlEncodedBody verwenden müssen, um Ihre Multipart zu testen, Sie sollten nur die richtige POST-Anfrage erstellen. – DamnWidget

2

Der einfachste Weg, dies zu tun, ist Scala wie folgt zu verwenden:

val formData = Map(
    "param-1" -> Seq("value-1"), 
    "param-2" -> Seq("value-2") 
) 
val result = routeAndCall(FakeRequest(POST, "/register").copy(body=formData)) 

Dieser Ihre Controller-Methode ist von der Form wird unter der Annahme:

def register = Action(parse.tolerantFormUrlEncoded) { ... } 

Wenn Sie wirklich Java verwenden müssen, Sie haben keinen Zugriff auf benannte Parameter, so dass die ‚Kopie‘ Methode oben müßte vollständig genannt werden. Achten Sie auch darauf, das scala play.api.test.FakeRequest-Objekt zu importieren, da der Java FakeRequest-Proxy über keine Kopiermethode verfügt.

+0

Kann Datei in den FormData erlaubt sein? – angelokh

2

Hier ist eine Lösung mit callAction() in Java, um den mehrteiligen/Formulardateninhalt für eine Anfrage zu erstellen. Es funktioniert zumindest in Play 2.2.3. Mein Inhaltstyp war application/zip. Möglicherweise möchten Sie dies ändern.

@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);