test java spring mocking spring-test-mvc

java - test - Cómo comprobar String en el cuerpo de respuesta con mockMvc



mockmvc jsonpath (8)

Tengo una prueba de integración simple

@Test public void shouldReturnErrorMessageToAdminWhenCreatingUserWithUsedUserName() throws Exception { mockMvc.perform(post("/api/users").header("Authorization", base64ForTestUser).contentType(MediaType.APPLICATION_JSON) .content("{/"userName/":/"testUserDetails/",/"firstName/":/"xxx/",/"lastName/":/"xxx/",/"password/":/"xxx/"}")) .andDo(print()) .andExpect(status().isBadRequest()) .andExpect(?); }

En la última línea, quiero comparar la cadena recibida en el cuerpo de respuesta con la cadena esperada

Y en respuesta consigo:

MockHttpServletResponse: Status = 400 Error message = null Headers = {Content-Type=[application/json]} Content type = application/json Body = "Username already taken" Forwarded URL = null Redirected URL = null

Intenté algunos trucos con contenido (), cuerpo () pero nada funcionó.


@Siririos Delimanolis responde hacer el trabajo, sin embargo, estaba buscando comparar cadenas dentro de esta aserción de mockMvc

Asi que aqui esta

.andExpect(content().string("/"Username already taken - please try with different username/""));

Por supuesto, mi afirmación falla:

java.lang.AssertionError: Response content expected: <"Username already taken - please try with different username"> but was:<"Something gone wrong">

porque:

MockHttpServletResponse: Body = "Something gone wrong"

¡Así que esta es una prueba de que funciona!


Al leer estas respuestas, puedo ver mucho relacionado con Spring versión 4.x, estoy usando la versión 3.2.0 por varias razones. Entonces, cosas como el soporte de json directamente desde el content() no es posible.

Descubrí que usar MockMvcResultMatchers.jsonPath es realmente fácil y funciona bien. Aquí hay un ejemplo que prueba un método de publicación.

La ventaja de esta solución es que todavía está haciendo coincidir atributos, sin depender de comparaciones completas de json string.

(Usando org.springframework.test.web.servlet.result.MockMvcResultMatchers )

String expectedData = "some value"; mockMvc.perform(post("/endPoint") .contentType(MediaType.APPLICATION_JSON) .content(mockRequestBodyAsString.getBytes())) .andExpect(status().isOk()) .andExpect(MockMvcResultMatchers.jsonPath("$.data").value(expectedData));

El cuerpo de la solicitud era solo una cadena json, que puedes cargar fácilmente desde un archivo de datos simulado json real si así lo deseas, pero no incluí eso aquí ya que se habría desviado de la pregunta.

El json real devuelto se habría visto así:

{ "data":"some value" }


El @WithMockUser @WithMockUser de Spring Spring y el string containsString hamcrest son una solución simple y elegante:

@Test @WithMockUser(roles = "USER") public void loginWithRoleUserThenExpectUserSpecificContent() throws Exception { mockMvc.perform(get("/index")) .andExpect(status().isOk()) .andExpect(content().string(containsString("This content is only shown to users."))); }

Más ejemplos en github


Para verificar el resultado html final, puede obtener todo el resultado HTML mediante el siguiente código y verificar los mensajes en él:

@Test public void testHtmlOutput() throws Exception { String htmlBody = this.restTemplate.getForObject("/mypage, String.class); assertThat(htmlBody.contains("any message in html output")); }

la plantilla de descanso se debe autoconectar:

@Autowired private TestRestTemplate restTemplate;

y assertThat debe importarse como un método estático:

import static org.assertj.core.api.Assertions.assertThat;


Puede invocar andReturn() y usar el objeto devuelto MvcResult para obtener el contenido como String . Vea abajo:

MvcResult result = mockMvc.perform(post("/api/users").header("Authorization", base64ForTestUser).contentType(MediaType.APPLICATION_JSON) .content("{/"userName/":/"testUserDetails/",/"firstName/":/"xxx/",/"lastName/":/"xxx/",/"password/":/"xxx/"}")) .andDo(print()) .andExpect(status().isBadRequest()) .andReturn(); String content = result.getResponse().getContentAsString(); // do what you will


Spring MockMvc ahora tiene soporte directo para JSON. Entonces solo dices:

.andExpect(content().json("{''message'':''ok''}"));

y a diferencia de la comparación de cadenas, dirá algo así como "campo faltante xyz" o "mensaje esperado ''ok'' obtenido ''nok''.

Este método fue introducido en Spring 4.1.


Tomado del tutorial de primavera

mockMvc.perform(get("/" + userName + "/bookmarks/" + this.bookmarkList.get(0).getId())) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) .andExpect(jsonPath("$.id", is(this.bookmarkList.get(0).getId().intValue()))) .andExpect(jsonPath("$.uri", is("http://bookmark.com/1/" + userName))) .andExpect(jsonPath("$.description", is("A description")));

is disponible en import static org.hamcrest.Matchers.*;

jsonPath está disponible en la import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;

y la referencia jsonPath se puede encontrar here


String body = mockMvc.perform(bla... bla).andReturn().getResolvedException().getMessage()

Esto debería darte el cuerpo de la respuesta. "Nombre de usuario ya tomado" en su caso.