[英]How to test a RestClientException with MockRestServiceServer
While testing a RestClient-Implementation I want to simulate a RestClientException that may be thrown by some RestTemplate-methods in that implementation fe the delete-method:在测试 RestClient-Implementation 时,我想模拟一个 RestClientException ,该异常可能由该实现中的某些 RestTemplate-methods fe 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);
}
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:它似乎在测试中有效:
RestTemplate
call,只有一个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
。
You can take advantage of the MockRestResponseCreators for 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());
在您的情况下,由于客户端 HTTP 错误会引发 RestClientException,因此可以使用以下示例对4xx
异常进行微调: ...andRespond(withBadRequest());
or ...andRespond(withStatus(HttpStatus.NOT_FOUND));
或...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
使用静态导入
Answer by Alex Ciocan works for different http status responses, so if you want those, go with that as that's the cleanest way to go. Alex Ciocan 的回答适用于不同的 http 状态响应,因此,如果您需要这些响应,请使用它,因为这是最干净的方法。 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.我遇到了一个问题,我需要能够测试连接重置和其他网络级问题,这些问题很难模拟。
Answer by MaDa works for some use cases, but it didn't work for me when using AsyncRestTemplate, as it throws too early. MaDa 的回答适用于某些用例,但在使用 AsyncRestTemplate 时对我不起作用,因为它抛出得太早。 However it did lead me to right direction.然而,它确实引导我走向正确的方向。 This one seems to work with async calls as well:这个似乎也适用于异步调用:
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 状态。
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());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.