2012-06-05 2 views
9

Я пытаюсь создать функциональный тест для контроллера Play 2, который принимает данные из нескольких форм в качестве входных данных. В настоящее время в FakeRequest нет метода поддержки многостраничного POST. Какие еще способы тестирования этого контроллера?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: Это обходной путь я сделал, чтобы проверить 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 для воспроизведения Framework 2, но я не думаю, что вы можете проверить многослойную форму, используя 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: Извините за мой английский, я все еще учусь

+0

Почему CallAction требуется для withFormUrlEncodeBody? routeAndCall также должен работать. routeAndCall (fakeRequest (POST, "/route").withFormUrlEncodedBody(map)); – angelokh

+0

Mutlipartformdata может работать для scala с вами методом. Тем не менее, для java, сFormUrlEncodedBody не позволит карте со значением в Тип объекта. – angelokh

+0

Я не знаю, почему callAction требуется для Java-вкуса, но похоже, что вы можете вызывать только fakeRequest(). WithFormUrlEncodeBody с callAction, во всяком случае, я мало знаю о языке Java, поэтому я могу быть совершенно неправ. Я не думаю, что вам нужно использовать withFormUrlEncodedBody для тестирования вашего multipart, вы должны только создать правильный запрос POST. – DamnWidget

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, вы не имеете доступа к именованным параметрам, поэтому метод «копирования» выше бы назвать в полном объеме. Также будьте осторожны, чтобы импортировать объект scala play.api.test.FakeRequest, поскольку прокси-сервер Java FakeRequest не имеет метода копирования.

+0

Можно ли разрешить файл в форматеДата? – angelokh

2

Вот решение с callAction() в Java, чтобы создать контент для многостраничного/форма-данных для запроса. Он работает, как минимум, в 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); 
} 
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);