Spring RestTemplate вызывает веб-сервис с ошибками и анализирует код состояния
Я разработал веб-сервис для выполнения задачи, если параметры запроса в порядке, или вернуть 401 Несанкционированный код состояния HTTP, если параметры запроса неверны или пусты.
Я использую RestTemplate
для выполнения теста, и я могу проверить статус HTTP 200 OK, если веб-служба отвечает с успехом. Однако я не могу протестировать ошибку HTTP 401, потому что RestTemplate
сам генерирует исключение.
Мой метод тестирования
@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());
}
Журнал исключений
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)
Как я могу проверить, отвечает ли webservice кодом состояния HTTP 401?
Ответы
Ответ 1
Вам нужно реализовать ResponseErrorHandler
, чтобы перехватить код ответа, тело и заголовок, когда вы получаете коды ответов, отличные от 2xx, из службы, используя шаблон отдыха. Скопируйте всю необходимую информацию, прикрепите ее к своему пользовательскому исключению и выбросите ее, чтобы вы могли ее поймать в своем тесте.
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;
}
}
Теперь, что вам нужно сделать в своем тесте, установите этот ResponseErrorHandler в 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]"));
}
Ответ 2
В качестве альтернативы решению, представленному nilesh, вы также можете использовать класс spring DefaultResponseErrorHandler. Вам также необходимо ovveride свой метод hasError (HttpStatus), чтобы он не генерировал исключение при неудачном результате.
restTemplate.setErrorHandler(new DefaultResponseErrorHandler(){
protected boolean hasError(HttpStatus statusCode) {
return false;
}});
Ответ 3
В моем сервисе отдыха я улавлю HttpStatusCodeException
вместо Exception
поскольку HttpStatusCodeException
имеет способ получения кода состояния
catch(HttpStatusCodeException e) {
log.debug("Status Code", e.getStatusCode());
}
Ответ 4
Вы можете использовать spring -test. Это намного проще:
@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()));
}
}
Ответ 5
Так как Spring 4.3, существует RestClientResponseException
, который содержит фактические данные ответа HTTP, такие как код состояния, тело ответа и заголовки. И вы можете поймать его.
RestClientResponseException Java Doc