2017-08-09 33 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的答案来确保您处理期望的异常 –