Cómo verificar la cadena en el cuerpo de la respuesta con mockMvc

Resuelto pbaranski asked hace 11 años • 15 respuestas

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 la respuesta con la cadena esperada.

Y en respuesta me sale:

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

Probé algunos trucos con content(), body() pero nada funcionó.

pbaranski avatar Aug 20 '13 20:08 pbaranski
Aceptado

Puede llamar andReturn()y utilizar el MvcResultobjeto devuelto para obtener el contenido como archivo 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(MockMvcResultHandlers.print())
            .andExpect(status().isBadRequest())
            .andReturn();

String content = result.getResponse().getContentAsString();
// do what you will 
Sotirios Delimanolis avatar Aug 20 '2013 13:08 Sotirios Delimanolis

La respuesta de @Sotirios Delimanolis hace el trabajo, sin embargo, estaba buscando comparar cadenas dentro de esta afirmación simulada de Mvc.

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 la prueba de que funciona!

pbaranski avatar Aug 20 '2013 17:08 pbaranski

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 como "campo faltante xyz" o "mensaje esperado 'ok' recibido 'nok'.

Este método se introdujo en Spring 4.1.

vertti avatar Jun 08 '2015 08:06 vertti

Al leer estas respuestas, puedo ver muchas cosas relacionadas con la versión 4.x de Spring. Estoy usando la versión 3.2.0 por varias razones. Por lo tanto, cosas como la compatibilidad con json directamente desde el content()no son posibles.

Descubrí que usarlo MockMvcResultMatchers.jsonPathes realmente fácil y funciona de maravilla. A continuación se muestra un ejemplo que prueba un método de publicación.

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

(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 puede cargar fácilmente desde un archivo de datos simulado json real si lo desea, pero no lo incluí aquí porque se habría desviado de la pregunta.

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

{
    "data":"some value"
}
Jeremy avatar Feb 05 '2016 14:02 Jeremy

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

isestá disponible desdeimport static org.hamcrest.Matchers.*;

jsonPathestá disponible desdeimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;

y jsonPathla referencia se puede encontrar aquí

user2829759 avatar Feb 14 '2018 10:02 user2829759