2012-06-05 13 views
9

Sto provando a creare un test di funzionalità per un controller di Play 2 che accetta come input dati di modulo multiparte. Al momento non esiste alcun metodo in FakeRequest per supportare il POST di form multipart. Quali altri modi per testare questo controller?Test MultipartFormData in Play 2.0 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: Questa è la soluzione che ho fatto per testare 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(); 
} 

risposta

7

Si dovrebbe usare callAction utilizzare 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) 
      ) 
      ... 
     } 
    } 
} 

Io uso solo Scala API for Gioca Framework 2, ma io non credo che si può verificare il modulo multipart utilizzando withFormUrlEncodedBody.

si può fare in questo modo a 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)) 
      ... 
     } 
    } 
} 

Credo che si può tradurre in Java, non so come codice in Java dispiace.

PD: Ci scusiamo per il mio inglese che sto ancora imparando

+0

Perché callAction è necessario per withFormUrlEncodeBody? routeAndCall dovrebbe funzionare anche. routeAndCall (fakeRequest (POST, "/route").withFormUrlEncodedBody(map)); – angelokh

+0

Mutlipartformdata potrebbe funzionare per il metodo scala con te. Tuttavia, per java, withFormUrlEncodedBody non consentirebbe una mappa con valore nel tipo di oggetto. – angelokh

+0

Non so perché callAction è richiesto su Java flavor ma sembra che tu possa solo chiamare fakeRequest(). ConFormUrlEncodeBody con callAction, comunque, non ne so molto del linguaggio Java, quindi posso sbagliarmi completamente. Non penso che tu debba usare con FormUrlEncodedBody per testare il tuo multipart, dovresti solo costruire la richiesta POST corretta. – DamnWidget

2

Il modo più semplice per farlo è quello di utilizzare Scala come segue:

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

Ciò presuppone il metodo di controllo è della forma:

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

Se davvero si deve utilizzare Java, non è necessario l'accesso ai parametri denominati, in modo che il metodo di 'copia' di cui sopra avrebbe dovuto essere chiamato in pieno. Inoltre, fai attenzione a importare l'oggetto scala play.api.test.FakeRequest, poiché il proxy Java FakeRequest non ha un metodo di copia.

+0

Il file può essere consentito nel formData? – angelokh

2

Ecco una soluzione con callAction() in Java per creare il contenuto multipart/form-data per una richiesta. Funziona almeno in Play 2.2.3. Il mio tipo di contenuto era application/zip. Potresti voler cambiare questo.

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