Тестирование сообщений формы через MockMVC

Я пишу тесты, чтобы убедиться, что я могу сделать общий пост формы для нашего API.

Я также добавил довольно некоторую отладку, но я заметил, что данные, опубликованные фактической формой; (Postman / AngularJS или w / e) отличается от выполнения теста mockMVC, как:

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

конфигурация точно такая же, как конфигурация, запущенная в производстве, и такая. Однако, когда мой перехватчик регистрирует содержимое, в реальном тесте (не mockMVC) содержимое форматируется как "someparam1=somevalue & etc=encore"

когда я печатаю содержимое mockMVC, у меня на самом деле нет контента, но в запросе есть параметры, я предполагаю, что они добавляются как параметры GET.

кто-нибудь знает, как правильно это проверить? Я столкнулся с этой проблемой, так как кажется, что наши сообщения формы, похоже, не анализируются весной, хотя у нас есть FormHttpMessageConverter, добавленный в контекст сервлета.

2 ответов


Если у вас есть Apache HTTPComponents HttpClient на вашем пути к классам, вы можете сделать это следующим образом:

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

Если у вас нет HttpClient, вы можете сделать это с помощью простого вспомогательного метода, который создает объект urlencoded form:

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

С этой вспомогательной функцией:

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

вы также можете использовать эту небольшую библиотеку, которую я создал:https://github.com/f-lopes/spring-mvc-test-utils/.

добавить зависимость в pom.XML-код:

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

используйте его с 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"));

эта библиотека просто добавляет параметры в запрос MockMvc в соответствии с объектом form.

вот подробный учебник, который я написал: https://blog.florianlopes.io/tool-for-spring-mockmvcrequestbuilder-forms-tests/