postforobject - Spring RestTemplate invocando el servicio web con errores y analiza el código de estado
resttemplate get status code (5)
Diseñé un servicio web para realizar una tarea si los parámetros de solicitud son correctos, o devuelvo el código de estado HTTP 401 no autorizado si los parámetros de solicitud son incorrectos o están vacíos.
Estoy usando RestTemplate
para realizar una prueba y puedo verificar el estado de HTTP 200 OK si el servicio web responde con éxito. Sin embargo, no puedo probar el error HTTP 401 porque RestTemplate
arroja una excepción.
Mi método de prueba es
@Test
public void testUnauthorized()
{
Map<String, Object> params = new HashMap<String, Object>();
ResponseEntity response = restTemplate.postForEntity(url, params, Map.class);
Assert.assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode());
Assert.assertNotNull(response.getBody());
}
El registro de excepciones es
org.springframework.web.client.HttpClientErrorException: 401 Unauthorized
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:88)
at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:533)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:489)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:447)
at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:318)
¿Cómo puedo probar si el servicio web responde con un código de estado HTTP 401?
Como alternativa a la solución presentada por nilesh, también podría usar la clase de primavera DefaultResponseErrorHandler. También necesita superar su método hasError (HttpStatus) para que no arroje ninguna excepción sobre el resultado no exitoso.
restTemplate.setErrorHandler(new DefaultResponseErrorHandler(){
protected boolean hasError(HttpStatus statusCode) {
return false;
}});
Debe implementar ResponseErrorHandler
para interceptar el código de respuesta, el cuerpo y el encabezado cuando obtiene códigos de respuesta que no son 2xx del servicio utilizando la plantilla de descanso. Copie toda la información que necesita, adjúntela a su excepción personalizada y tírela para que pueda verla en su prueba.
public class CustomResponseErrorHandler implements ResponseErrorHandler {
private ResponseErrorHandler errorHandler = new DefaultResponseErrorHandler();
public boolean hasError(ClientHttpResponse response) throws IOException {
return errorHandler.hasError(response);
}
public void handleError(ClientHttpResponse response) throws IOException {
String theString = IOUtils.toString(response.getBody());
CustomException exception = new CustomException();
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("code", response.getStatusCode().toString());
properties.put("body", theString);
properties.put("header", response.getHeaders());
exception.setProperties(properties);
throw exception;
}
}
Ahora lo que debe hacer en su prueba es configurar este ResponseErrorHandler en RestTemplate,
RestTemplate restclient = new RestTemplate();
restclient.setErrorHandler(new CustomResponseErrorHandler());
try {
POJO pojo = restclient.getForObject(url, POJO.class);
} catch (CustomException e) {
Assert.isTrue(e.getProperties().get("body")
.equals("bad response"));
Assert.isTrue(e.getProperties().get("code").equals("400"));
Assert.isTrue(((HttpHeaders) e.getProperties().get("header"))
.get("fancyheader").toString().equals("[nilesh]"));
}
Desde Spring 4.3, hay una RestClientResponseException
que contiene datos de respuesta HTTP reales, como el código de estado, el cuerpo de respuesta y los encabezados. Y puedes atraparlo.
En mi servicio de descanso capturo HttpStatusCodeException
lugar de Exception
ya que HttpStatusCodeException
tiene un método para obtener el código de estado
catch(HttpStatusCodeException e) {
log.debug("Status Code", e.getStatusCode());
}
Puedes usar spring-test. Es mucho más fácil:
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:your-context.xml")
public class BasicControllerTest {
@Autowired
protected WebApplicationContext wac;
protected MockMvc mockMvc;
@Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
public void testUnauthorized(){
mockMvc.perform(MockMvcRequestBuilders
.post("your_url")
.param("name", "values")
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isUnauthorized()
.andExpect(MockMvcResultMatchers.content().string(Matchers.notNullValue()));
}
}