2012-06-05 16 views
9

Estoy tratando de crear una prueba de función para un controlador Play 2 que toma datos de formulario multiparte como entrada. No hay ningún método actualmente en FakeRequest para admitir el formulario POST de varias partes. ¿Qué otras formas de probar este controlador?Prueba MultipartFormData en 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: Esta es la solución que hice para probar varias partes.

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

Respuesta

7

Debe utilizar callAction utilizar 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) 
      ) 
      ... 
     } 
    } 
} 

utilizo solamente Scala API for Juega marco 2, pero yo no creo que se pueda probar el formulario de varias partes utilizando withFormUrlEncodedBody.

Puede hacerlo de esta manera en 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)) 
      ... 
     } 
    } 
} 

supongo que se puede traducir a Java, no sé cómo el código en Java lo siento. Lo siento por mi Inglés Todavía estoy aprendiendo

+0

Por qué se requiere para callAction withFormUrlEncodeBody? routeAndCall también debería funcionar. routeAndCall (fakeRequest (POST, "/route").withFormUrlEncodedBody(map)); – angelokh

+0

Datos de Mutlipartform podría funcionar para Scala con usted método. Sin embargo, para java, withFormUrlEncodedBody no permitiría un mapa con valor en Tipo de objeto. – angelokh

+0

No sé por qué se requiere callAction en el sabor de Java, pero parece que solo se puede llamar a fakeRequest() .withFormUrlEncodeBody con callAction, de todos modos, no sé mucho sobre el lenguaje Java, así que puedo estar completamente equivocado. No creo que deba usar withFormUrlEncodedBody para probar su multiparte, solo debería compilar la solicitud POST correcta. – DamnWidget

2

La forma más sencilla de hacerlo es utilizar Scala de la siguiente manera::

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

Esto es suponiendo que su método de control es de la forma

PD

:

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

Si realmente tiene que utilizar Java, usted no tiene acceso a los parámetros con nombre, por lo que el método de 'copia' de arriba tendría que ser llamado en su totalidad. También tenga cuidado de importar el objeto scala play.api.test.FakeRequest, ya que el proxy Java FakeRequest no tiene un método de copia.

+0

¿Se puede permitir el archivo en formData? – angelokh

2

Aquí hay una solución con callAction() en Java para crear el contenido multipart/form-data para una solicitud. Funciona al menos en Play 2.2.3. Mi tipo de contenido era application/zip. Es posible que desee cambiar esto.

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