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 obtengo:
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 content (), body () pero nada funcionó.
java
spring
mocking
spring-test-mvc
pbaranski
fuente
fuente

"Username already taken". Eso debería ser más de un conflicto 409.Respuestas:
Puede llamar
andReturn()y usar elMvcResultobjeto devuelto para obtener el contenido como aString.Vea abajo:
fuente
@RestControllerindica que todos los métodos de manejo están implícitamente anotados con@ResponseBody. Esto significa que Spring usará aHttpMessageConverterpara serializar el valor de retorno del controlador y escribirlo en la respuesta. Puedes conseguir mucho el cuerpocontent().getContentAsString()que vino de mi@RestControllercontrolador anotado.result.getResponse().getErrorMessage()andReturndevuelve unMvcResult, como se especifica en el javadoc aquí .La respuesta de @Sotirios Delimanolis hace el trabajo, sin embargo, estaba buscando comparar cadenas dentro de esta afirmación de mockMvc
Asi que aqui esta
Por supuesto, mi afirmación falla:
porque:
¡Entonces esta es una prueba de que funciona!
fuente
.andExpect(content().string(containsString("\"Username already taken");org.hamcrest.Matchers.containsString().org.hamcrest.Matchers.equalToIgnoringWhiteSpace()matcher para ignorar todos los caracteres de espacio en blanco. Tal vez sea un consejo útil para alguienSpring MockMvc ahora tiene soporte directo para JSON. Entonces solo dices:
y a diferencia de la comparación de cadenas, dirá algo como "campo faltante xyz" o "mensaje Esperado 'ok' consiguió 'nok'.
Este método fue introducido en Spring 4.1.
fuente
ContentRequestMatchersque también admita esta función?Al leer estas respuestas, puedo ver muchas cosas relacionadas 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.jsonPathes realmente fácil y funciona muy bien. Aquí hay un ejemplo que prueba un método de publicación.La ventaja con esta solución es que todavía está haciendo coincidir los atributos, no confiando en comparaciones completas de cadenas json.
(Usando
org.springframework.test.web.servlet.result.MockMvcResultMatchers)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í ya que se habría desviado de la pregunta.
El json real devuelto se habría visto así:
fuente
Tomado del tutorial de primavera
isestá disponible desdeimport static org.hamcrest.Matchers.*;jsonPathestá disponible desdeimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;y
jsonPathreferencia se puede encontrar aquífuente
error: incompatible types: RequestMatcher cannot be converted to ResultMatcherpor.andExpect(content().contentType(contentType))La
@WithMockUsercombinación de Spring Security y Hamcrest escontainsStringuna solución simple y elegante:Más ejemplos en github
fuente
Aquí hay un ejemplo de cómo analizar la respuesta JSON e incluso cómo enviar una solicitud con un bean en forma JSON:
Como puede ver aquí,
Bookhay un DTO de solicitud yUpdateBookResponseun objeto de respuesta analizado desde JSON. Es posible que desee cambiar laObjectMapperconfiguración de Jakson .fuente
Esto debería darle el cuerpo de la respuesta. "Nombre de usuario ya tomado" en su caso.
fuente
aquí una manera más elegante
fuente
Puede usar el método 'getContentAsString' para obtener los datos de respuesta como una cadena.
Puede consultar este enlace para la aplicación de prueba.
fuente
Un posible enfoque es simplemente incluir la
gsondependencia:y analiza el valor para hacer tus verificaciones:
fuente