web-dev-qa-db-ja.com

エラーを伴うWebサービスを呼び出し、ステータスコードを分析するSpring RestTemplate

要求パラメーターがOKの場合にタスクを実行するようにWebサービスを設計し、要求パラメーターが間違っているか空の場合は401 Unauthorized HTTPステータスコードを返します。

RestTemplateを使用してテストを実行し、Webサービスが成功と応答した場合、HTTP 200 OKステータスを確認できます。ただし、RestTemplate自体が例外をスローするため、HTTP 401エラーをテストできません。

私のテスト方法は

@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)

WebサービスがHTTPステータスコード401で応答するかどうかをテストするにはどうすればよいですか?

30
Premier

レストテンプレートを使用してサービスから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]"));
}
48
nilesh

Nileshが提供するソリューションの代替として、SpringクラスDefaultResponseErrorHandlerを使用することもできます。また、失敗した結果で例外をスローしないように、hasError(HttpStatus)メソッドを確認する必要があります。

restTemplate.setErrorHandler(new DefaultResponseErrorHandler(){
    protected boolean hasError(HttpStatus statusCode) {
        return false;
    }});
29
Ramps

残りのサービスでは、HttpStatusCodeExceptionにはステータスコードを取得するメソッドがあるため、ExceptionではなくHttpStatusCodeExceptionをキャッチします。

catch(HttpStatusCodeException e) {
    log.debug("Status Code", e.getStatusCode());
}
7
ericdemo07

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
chaldaean

Spring 4.3以降、ステータスコード、レスポンスボディ、ヘッダーなどの実際のHTTPレスポンスデータを含むRestClientResponseExceptionがあります。そして、あなたはそれをキャッチすることができます。

RestClientResponseException Java Doc

4
zhouji