2013-03-14 3 views
26

リクエストパラメータがOKの場合にタスクを実行するようにWebサービスを設計しました。リクエストパラメータが間違っているか空である場合は、401 Unauthorized HTTPステータスコードを返します。Spring RestTemplateがエラーでwebserviceを呼び出し、ステータスコードを分析する

私はRestTemplateを使用してテストを行っています。ウェブサービスが成功した場合、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で応答した場合、私はテストすることができますか?

+0

私の答えはあなたのために機能しましたか? – nilesh

答えて

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())); 
     } 
} 
+1

これは、スプリングがデフォルトでフィルタを介してテストを実行しないため、ヘッダーに認証を追加する必要がある場合には機能しません。 – snowe

44

あなたは残りのテンプレートを使用してサービスから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; 
    } 
} 

は今、あなたは、nileshが提示する解決策の代替として

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

このパターンに従うと、CustomExceptionは未チェックの例外です。例えば、RuntimeExceptionを拡張することができます。それ以外の場合、例外はそのメソッドの "throws IOException"に渡すことはできません。 –

+0

注:私はポストリクエストを使用しています – snowe

+0

@ snowe2010あなたはHttpCustomExceptionを取得するために以下を行うことができます。 ------> catch(Exception e){if(e.getCause()instanceof HttpCustomException){ \t HttpCustomException customException =(HttpCustomException)e.getCause(); \t l.warn( "残りのテンプレートのカスタム例外"); }} – Maximus

24

、同様RestTemplateでこのResponseErrorHandlerに設定されているテストで何をする必要があるか、あなたはまた、春のクラスDefaultResponseErrorHandlerを使用することができます。また、hasError(HttpStatus)メソッドをovverideして、成功しなかった結果に対して例外をスローしないようにする必要があります。私のRESTサービスで

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

これは私にとって本当にうまくいった。使用するAPIがJSONエラーを返すため、スローされた例外は私にそれを見ることを禁止していました。これにより、デバッグに十分な柔軟性が得られました。 – Sion

+1

最後に、私の問題を解決しました。ありがとうございました.... – KJEjava48

7

私の代わりにExceptionHttpStatusCodeExceptionをキャッチHttpStatusCodeException春4.3ので、ステータスコード

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

、これはうまくいきます。応答コンテンツにアクセスする必要がある場合は、HttpClientErrorExceptionおよび/またはHttpServerErrorExceptionを捕捉できます。 – chrismarx

+1

私の2セント:TestRestTemplateクラス(Spring Boot)を使用している場合、catch(RestClientException)を使用する必要があります。 –

2

を取得するためのメソッドを持っているため、実際のHTTPレスポンスデータを含むRestClientResponseExceptionがあり、ステータスコード、応答本文、ヘッダーなど)。そしてあなたはそれをキャッチすることができます。

RestClientResponseException Java Doc

関連する問題