如何使用 MockRestServiceServer 测试 RestClientException
How to test a RestClientException with MockRestServiceServer
在测试 RestClient-Implementation 时,我想模拟一个 RestClientException,它可能会被该实现中的某些 RestTemplate 方法抛出 f.e。删除方法:
@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;
}
我怎样才能做到这一点?
我这样定义模拟服务器:
@Before
public void setUp() {
mockServer = MockRestServiceServer.createServer(template);
client = new MyRestClient(template, serverUrl + ":" + serverPort);
}
您可以利用 MockRestResponseCreators 模拟来自 mockRestServiceServer 的 4xx 或 5xx 响应。
例如测试 5xx - 内部服务器错误:
mockServer.expect(requestTo("your.url"))
.andExpect(method(HttpMethod.GET/POST....))
.andRespond(withServerError()...);
在你的例子中,客户端 HTTP 错误抛出 RestClientException,所以
可以使用以下方法针对 4xx
异常对上面的示例进行微调:
...andRespond(withBadRequest());
或 ...andRespond(withStatus(HttpStatus.NOT_FOUND));
为了更简单地使用这些方法,您可以为 org.springframework.test.web.client.MockRestServiceServer
、org.springframework.test.web.client.response.MockRestResponseCreators
使用静态导入
您可以测试从 MockRestServiceServer
抛出运行时异常,尽管从 Spring 5.0.0.RC4 开始,这个 class 不是为它设计的(这意味着它可能不适用于更复杂的用例):
RestTemplate yourApi;
MockRestServiceServer server = MockRestServiceServer.createServer(yourApi);
server.expect(requestTo("http://..."))
.andRespond((response) -> { throw new ResourceAccessException(
new ConnectException("Connection reset")); });
它似乎在测试中有效:
- 只有一个
RestTemplate
调用,
- 由于最后的期望而抛出异常的地方。
我没想到会连续出现两次异常; MockRestSeriviceServer
(更具体地说,SimpleRequestExpectationManager
)在重播第二个期望时抛出 IllegalStateException
。
适用于不同的 http 状态响应,因此如果您需要这些响应,请使用它,因为这是最简洁的方法。我遇到了一个问题,我还需要能够测试连接重置和其他网络级问题,这些问题很难模拟。
适用于某些用例,但在使用 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);
这似乎也适用于连续异常以及不同的 http 状态。
这个怎么样:
@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());
}
在测试 RestClient-Implementation 时,我想模拟一个 RestClientException,它可能会被该实现中的某些 RestTemplate 方法抛出 f.e。删除方法:
@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;
}
我怎样才能做到这一点?
我这样定义模拟服务器:
@Before
public void setUp() {
mockServer = MockRestServiceServer.createServer(template);
client = new MyRestClient(template, serverUrl + ":" + serverPort);
}
您可以利用 MockRestResponseCreators 模拟来自 mockRestServiceServer 的 4xx 或 5xx 响应。
例如测试 5xx - 内部服务器错误:
mockServer.expect(requestTo("your.url"))
.andExpect(method(HttpMethod.GET/POST....))
.andRespond(withServerError()...);
在你的例子中,客户端 HTTP 错误抛出 RestClientException,所以
可以使用以下方法针对 4xx
异常对上面的示例进行微调:
...andRespond(withBadRequest());
或 ...andRespond(withStatus(HttpStatus.NOT_FOUND));
为了更简单地使用这些方法,您可以为 org.springframework.test.web.client.MockRestServiceServer
、org.springframework.test.web.client.response.MockRestResponseCreators
您可以测试从 MockRestServiceServer
抛出运行时异常,尽管从 Spring 5.0.0.RC4 开始,这个 class 不是为它设计的(这意味着它可能不适用于更复杂的用例):
RestTemplate yourApi;
MockRestServiceServer server = MockRestServiceServer.createServer(yourApi);
server.expect(requestTo("http://..."))
.andRespond((response) -> { throw new ResourceAccessException(
new ConnectException("Connection reset")); });
它似乎在测试中有效:
- 只有一个
RestTemplate
调用, - 由于最后的期望而抛出异常的地方。
我没想到会连续出现两次异常; MockRestSeriviceServer
(更具体地说,SimpleRequestExpectationManager
)在重播第二个期望时抛出 IllegalStateException
。
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);
这似乎也适用于连续异常以及不同的 http 状态。
这个怎么样:
@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());
}