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 elMvcResult
objeto devuelto para obtener el contenido como aString
.Vea abajo:
fuente
@RestController
indica que todos los métodos de manejo están implícitamente anotados con@ResponseBody
. Esto significa que Spring usará aHttpMessageConverter
para serializar el valor de retorno del controlador y escribirlo en la respuesta. Puedes conseguir mucho el cuerpocontent()
.getContentAsString()
que vino de mi@RestController
controlador anotado.result.getResponse().getErrorMessage()
andReturn
devuelve 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
ContentRequestMatchers
que 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.jsonPath
es 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
is
está disponible desdeimport static org.hamcrest.Matchers.*;
jsonPath
está disponible desdeimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
y
jsonPath
referencia se puede encontrar aquífuente
error: incompatible types: RequestMatcher cannot be converted to ResultMatcher
por.andExpect(content().contentType(contentType))
La
@WithMockUser
combinación de Spring Security y Hamcrest escontainsString
una 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í,
Book
hay un DTO de solicitud yUpdateBookResponse
un objeto de respuesta analizado desde JSON. Es posible que desee cambiar laObjectMapper
configuració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
gson
dependencia:y analiza el valor para hacer tus verificaciones:
fuente