如果请求参数正常,我设计了一个web服务来执行任务,或者如果请求参数错误或为空,我会返回401 Unauthorized HTTP状态代码。
我正在使用RestTemplate
执行测试,如果webservice成功回复,我就能验证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?
答案 0 :(得分:48)
当您使用rest模板从服务获取非2xx响应代码时,您需要实现ResponseErrorHandler
以拦截响应代码,正文和标头。复制您需要的所有信息,将其附加到您的自定义异常并抛出它,以便您可以在测试中捕获它。
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;
}
}
现在你需要在测试中做的是,在RestTemplate中设置这个ResponseErrorHandler,如,
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]"));
}
答案 1 :(得分:28)
作为nilesh提供的解决方案的替代方案,您还可以使用spring类DefaultResponseErrorHandler。您还需要遍历其hasError(HttpStatus)方法,以便它不会在非成功结果上抛出异常。
restTemplate.setErrorHandler(new DefaultResponseErrorHandler(){
protected boolean hasError(HttpStatus statusCode) {
return false;
}});
答案 2 :(得分:7)
在我的休息服务中,我抓住了HttpStatusCodeException
而不是Exception
因为HttpStatusCodeException
有一个获取状态代码的方法
catch(HttpStatusCodeException e) {
log.debug("Status Code", e.getStatusCode());
}
答案 3 :(得分:5)
您可以使用弹簧测试。这更容易:
@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()));
}
}
答案 4 :(得分:4)
从Spring 4.3开始,有一个RestClientResponseException
包含实际的HTTP响应数据,例如状态代码,响应正文和标题。你可以抓住它。