2017-08-09 30 views
0

我在我的代碼中使用了restTemplate.postForEntity()。 當測試它周圍的類時,我使用Mockito來模擬RestTemplate。如何用Client或Server錯誤模擬RestTemplate?

Mockito.when(restTemplate.postForEntity(.....)).thenReturn(response)

,其中反應是:

ResponseEntity<String> response = new ResponseEntity(HttpStatus.UNAUTHORIZED);

現在,當我運行這個測試,postForEntity返回模擬響應我剛纔給。但是,在實際執行中,RestTemplate在從遠程接收到401時會拋出RestClientException

這是因爲doExecute()RestTemplate檢查錯誤並在4XX和5XX錯誤的情況下引發此異常。

我當然可以改寫模擬規則:

Mockito.when(restTemplate.postForEntity(.....)).thenThrow(new RestClientException(..))

但是在閱讀測試時,這不是很直觀:我希望它響應401或500本身。

我該怎麼做才能做到這一點?

+0

要走的路是'thenThrow(新RestClientException(..)'如果你嘲笑'RestTemplate'(注意你也可以使用真正的RestTemplate和[模擬Http服務器](https://www.google.com/search?q=mock+http+server)) – 2017-08-09 17:30:09

回答

2

你已經在你的問題中說過:你在嘲笑RestTemplate並測試一個使用它的類。你不會扼殺它,只是嘲笑。

如果您希望RestTemplate根據它收到的http狀態拋出異常,那麼您需要模擬RestTemplate使用的內部客戶端,並在調用它時返回狀態碼。然後,您的RestTemplate應該被存根(或使用真正的實現)來對該http狀態作出反應。

但在我看來,這不是你想要測試的。

如果你只是談論測試的可讀性(但不斷測試你正在測試的東西),那麼我會建議創建一個基於http狀態生成mockito Answer的方法。如果狀態不是200那麼答案應該會引發異常。

所以,在你resttemplate嘲笑你會:

when(restTemplate.postForEntity(...)) 
    .thenAnswer(answer(401)); 

和回答實現類似:

private Answer answer(int httpStatus) { 
    return (invocation) -> { 
     if (httpStatus >= 400) { 
      throw new RestClientException(...); 
     } 
     return <whatever>; 
    }; 
} 

這只是一個例子,你需要去適應您的特定需求。

+0

我可能會更進一步,並根據RestTemplate使用的DefaultErrorDecoder的答案來確保您處理期望的異常 –