2016-04-12 16 views
9

Piszę testy, aby sprawdzić, czy mogę utworzyć ogólny formularz do naszego interfejsu API.Testowanie postów w formularzu za pośrednictwem MockMVC

Dodałem także trochę debugowania, ale zauważyłem, że dane publikowane przez rzeczywisty formularz; (Listonosz/angularjs lub w/e) różni się od robienia testu mockMVC jak:

MvcResult response = mockMvc 
      .perform(post("/some/super/secret/url") // 
        .param("someparam1", "somevalue") // 
        .param("someparam2", "somevalue") //     
        .contentType(MediaType.APPLICATION_FORM_URLENCODED) // 
        .accept(MediaType.APPLICATION_JSON)) // 
      .andExpect(status().isOk()) // 
      .andReturn(); 

config jest dokładnie taka sama, jak w konfiguracji z systemem produkcji, i takie. Jednak Kiedy mój przechwytujących rejestruje zawartość, prawdziwy test (nie mockMVC) treść jest sformatowana jak „someparam1 = someValue & etc = bis”

Kiedy wydrukować zawartość mockMVC I rzeczywiście wydają się mieć żadnej zawartości, ale istnieją Params w żądaniu, zakładam, że są one dodane jak parametry GET.

Ktoś wie, jak to właściwie przetestować? Natknąłem się na ten problem, ponieważ wydaje się, że nasze posty na formularzu nie są analizowane przez Spring, mimo że do kontekstu serwletu dodano FormHttpMessageConverter.

+0

mogę podać więcej szczegółów, jak config, prawdziwe dane wysłaniu do serwera i dość szczegółowo dziennika aby uczynić go bardziej jasne? O tym, co robisz, wygląda na to, że masz rację, param testowy to taki sam format wyświetlanych danych postów. Sprawdź też, czy myślisz o bezpieczeństwie wiosennym. Być może będziesz musiał sfałszować zabezpieczenia wiosenne lub wykonać logowanie przed wykonaniem kolejnych kroków. –

+1

Nie używamy niczego takiego, dowiedziałem się, że mój przykład jest w rzeczywistości błędny. w tym przypadku niektóreParam1 i niektóreParam2 będą parametrem zapytania, (W url). Chcę użyć parametrów formularza, a więc URLENCODED. To jednak wydaje się być dostępne tylko poprzez model lub mapę wartości. Będziemy więc potrzebować obejścia (zostało to zmigrowane, aby było w pełni wiosennym mvc, używanym jako @FormParam, który nie jest wiosną). –

+0

Och, również opublikowane dane, były jak w moim przykładzie poniżej części Mvc, publikuje ciąg zawartości zakończony znakiem & i = –

Odpowiedz

10

Jeśli masz Apache HTTPComponents HttpClient na ścieżce klas, można zrobić to tak:

mockMvc.perform(post("/some/super/secret/url") 
      .contentType(MediaType.APPLICATION_FORM_URLENCODED) 
      .content(EntityUtils.toString(new UrlEncodedFormEntity(Arrays.asList(
        new BasicNameValuePair("someparam1", "true"), 
        new BasicNameValuePair("someparam2", "test") 
      ))))); 

Jeśli nie masz HttpClient, można to zrobić za pomocą prostej metody pomocnika, który konstruuje postać urlencoded podmiot:

mockMvc.perform(post("/some/super/secret/url") 
      .contentType(MediaType.APPLICATION_FORM_URLENCODED) 
      .content(buildUrlEncodedFormEntity(
     "someparam1", "value1", 
     "someparam2", "value2" 
    )))); 

Dzięki tej funkcji pomocnika:

String buildUrlEncodedFormEntity(String... params) { 
    if((params.length%2)>0) { 
     throw new IllegalArgumentException("Need to give an even number of parameters"); 
    } 
    StringBuilder result = new StringBuilder(); 
    for(int i=0; i<params.length; i+=2) { 
     if(i>0) result.append('&'); 
     result.append(URLEncoder.encode(params[i]) 
      .append('=') 
      .append(URLEncoder.encode(params[i+1]); 
    } 
    return result.toString(); 
} 
+0

To nie jest najlepsze, ale jest to rozwiązanie. Czy możesz mi powiedzieć, dlaczego potrzebujesz Apache HTTPComponents?O ile widzę, jest to możliwe bez dodatkowych bibliotek. Na razie jako jedyna odpowiedź, przyjmuję to, wydaje się, że trudno przetestować w MockMVC –

+1

Dlaczego uważasz, że moje rozwiązanie nie jest dobre? Nie potrzebujesz HTTPComponents, po prostu go użyłem, ponieważ i tak miałem go w ścieżce klas. Możesz użyć dowolnej biblioteki, która jest w stanie zbudować encję zakodowaną w postaci kodu, która jest niczym więcej niż 'urlencode ('name1') + '=' + urlencode (value1) + '&' + ...'. Możesz napisać własną metodę pomocnika, aby ją zbudować. –

+0

Chyba miałem na myśli, że byłoby ładniej, gdyby była implementacja w mockMVC, działa to dobrze i jest w porządku, ale pozostaje to tylko możliwe. Funny Widzę, że odpowiedziałem po tym, jak nie pracowałem przez jakiś czas z Javą –

1

Ty coul d również użyć tej małej biblioteki, którą utworzyłem: https://github.com/f-lopes/spring-mvc-test-utils/.

dodawania zależność w pom.xml:

<dependency> 
    <groupId>io.florianlopes</groupId> 
    <artifactId>spring-mvc-test-utils</artifactId> 
    <version>1.0.1</version> 
    <scope>test</scope> 
</dependency> 

Użyj go z MockMvc:

mockMvc.perform(MockMvcRequestBuilderUtils.postForm("/users", new AddUserForm("John", "Doe", null, new Address(1, "Street", 5222, "New York")))) 
    .andExpect(MockMvcResultMatchers.status().isFound()) 
    .andExpect(MockMvcResultMatchers.redirectedUrl("/users")) 
    .andExpect(MockMvcResultMatchers.flash().attribute("message", "success")); 

Biblioteka ta po prostu dodaje parametry do wniosku MockMvc, w zależności od obiektu formularza.

Oto szczegółowy poradnik napisałem: https://blog.florianlopes.io/tool-for-spring-mockmvcrequestbuilder-forms-tests/

+2

Możesz przeczytać [Jak zaoferować osobiste biblioteki open-source?] (// meta.stackexchange.com/q/229085) –