java 如何使用 MockRestServiceServer 测试 RestClientException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42577392/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to test a RestClientException with MockRestServiceServer
提问by JMarky
While testing a RestClient-Implementation I want to simulate a RestClientException that may be thrown by some RestTemplate-methods in that implementation f.e. the delete-method:
在测试 RestClient-Implementation 时,我想模拟一个 RestClientException,该异常可能由该实现中的某些 RestTemplate-methods fe the delete-method 抛出:
@Override
public ResponseEntity<MyResponseModel> documentDelete(String id) {
template.setErrorHandler(new MyResponseErrorHandler());
ResponseEntity<MyResponseModel> response = null;
try {
String url = baseUrl + "/document/id/{id}";
response = template.exchange(url, DELETE, null, MyResponseModel.class, id);
} catch (RestClientException ex) {
return handleException(ex);
}
return response;
}
How can I achieve this?
我怎样才能做到这一点?
I define the mock-server in this way:
我以这种方式定义模拟服务器:
@Before
public void setUp() {
mockServer = MockRestServiceServer.createServer(template);
client = new MyRestClient(template, serverUrl + ":" + serverPort);
}
采纳答案by Alex Ciocan
You can take advantage of the MockRestResponseCreatorsfor mocking 4xx or 5xx responses from the mockRestServiceServer.
您可以利用MockRestResponseCreators来模拟来自 mockRestServiceServer 的 4xx 或 5xx 响应。
For example for testing a 5xx - Internal server error:
例如测试 5xx - 内部服务器错误:
mockServer.expect(requestTo("your.url"))
.andExpect(method(HttpMethod.GET/POST....))
.andRespond(withServerError()...);
In your case the RestClientException is thrown for client-side HTTP errors, so
the example above can be fine tuned for a 4xx
exception by using:
...andRespond(withBadRequest());
or ...andRespond(withStatus(HttpStatus.NOT_FOUND));
你的情况RestClientException抛出用于客户端的HTTP错误,所以上面的例子中可以被微调用于4xx
通过使用异常:
...andRespond(withBadRequest());
或...andRespond(withStatus(HttpStatus.NOT_FOUND));
For a more simpler usage of these methods you use static imports for org.springframework.test.web.client.MockRestServiceServer
,org.springframework.test.web.client.response.MockRestResponseCreators
为了更简单地使用这些方法,您可以使用静态导入org.springframework.test.web.client.MockRestServiceServer
,org.springframework.test.web.client.response.MockRestResponseCreators
回答by MaDa
You can test throwing runtime exceptions from the MockRestServiceServer
, although this class, as of Spring 5.0.0.RC4, is not designed for it (which means it may not work for more complex use cases):
您可以测试从 抛出运行时异常MockRestServiceServer
,尽管从Spring 5.0.0.RC4 开始,此类不是为它设计的(这意味着它可能不适用于更复杂的用例):
RestTemplate yourApi;
MockRestServiceServer server = MockRestServiceServer.createServer(yourApi);
server.expect(requestTo("http://..."))
.andRespond((response) -> { throw new ResourceAccessException(
new ConnectException("Connection reset")); });
It seems to work in tests:
它似乎在测试中有效:
- where there's only one
RestTemplate
call, - where the exception is thrown as a result of the last expectation.
- 只有一个
RestTemplate
电话的地方, - 由于最后的期望而抛出异常的地方。
I wasn't able to expect two consecutive exceptions; the MockRestSeriviceServer
(more concrete, the SimpleRequestExpectationManager
) throws IllegalStateException
on replaying the second expectation.
我无法预料到连续出现两次异常;的MockRestSeriviceServer
(更具体的,所述SimpleRequestExpectationManager
)抛出IllegalStateException
上重放所述第二期望。
回答by eis
Answer by Alex Ciocanworks for different http status responses, so if you want those, go with that as that's the cleanest way to go. I had a problem that I needed to be able to test also for connection reset and other network-level problems, which are trickier to simulate.
Alex Ciocan 的回答适用于不同的 http 状态响应,所以如果你想要这些,那就去吧,因为这是最干净的方式。我遇到了一个问题,我需要能够测试连接重置和其他网络级问题,这些问题很难模拟。
Answer by MaDaworks for some use cases, but it didn't work for me when using AsyncRestTemplate, as it throws too early. However it did lead me to right direction. This one seems to work with async calls as well:
MaDa 的回答适用于某些用例,但在使用 AsyncRestTemplate 时对我不起作用,因为它抛出得太早。然而,它确实引导我走向正确的方向。这个似乎也适用于异步调用:
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
// ...
ClientHttpResponse exceptionThrowingResponse = mock(ClientHttpResponse.class);
when(exceptionThrowingResponse.getStatusCode()) // getRawStatusCode() in latest spring
.thenThrow(new IOException("connection reset"));
mockServer.expect(requestTo("http://localhost:123/callme"))
.andRespond((response) -> exceptionThrowingResponse);
This seems to also work for consecutive exceptions, as well as different http statuses.
这似乎也适用于连续异常以及不同的 http 状态。
回答by Alferd Nobel
How about this :
这个怎么样 :
@Spy
@InjectMocks
ClasstoMock objToMock;
@Test
public void testRestClientException() throws Exception {
try {
Mockito.when(this.objToMock.perform()).thenThrow(new RestClientException("Rest Client Exception"));
this.objToMock.perform();
}
catch(Exception e){
Assert.assertEquals(RestClientException.class, e.getClass());
}