Java 如何使用MockRestServiceServer测试RestClientException
在测试RestClient实现时,我想模拟一个RestClientException,该实现中的一些RestTemplate方法可能引发该异常,例如delete方法:Java 如何使用MockRestServiceServer测试RestClientException,java,spring,mocking,mockserver,Java,Spring,Mocking,Mockserver,在测试RestClient实现时,我想模拟一个RestClientException,该实现中的一些RestTemplate方法可能引发该异常,例如delete方法: 您可以利用来模拟来自mockRestServiceServer的4xx或5xx响应 例如,测试5xx-内部服务器错误: mockServer.expect(requestTo("your.url")) .andExpect(method(HttpMethod.GET/POST....))
您可以利用来模拟来自mockRestServiceServer的4xx或5xx响应 例如,测试5xx-内部服务器错误:
mockServer.expect(requestTo("your.url"))
.andExpect(method(HttpMethod.GET/POST....))
.andRespond(withServerError()...);
在您的例子中,RestClientException是针对客户端HTTP错误引发的,因此
通过使用以下方法,可以针对4xx
异常对上述示例进行微调:
…并响应(withBadRequest())代码>或…和响应(使用status(HttpStatus.NOT_FOUND))代码>
要更简单地使用这些方法,请对org.springframework.test.web.client.MockRestServiceServer
,org.springframework.test.web.client.responseSecreators使用静态导入
您可以从MockRestServiceServer
测试抛出运行时异常,尽管从Spring 5.0.0.RC4开始,该类不是为它设计的(这意味着它可能无法用于更复杂的用例):
它似乎在测试中起作用:
- 其中只有一个
restemplate
调用
- 作为最后一个期望的结果引发异常
我不能期望连续两次出现异常;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());
}
陛下好的,我可以使用builder方法最终创建ClientHttpResponse,但是如何通过builder方法微调这样的响应,以便引发/模拟异常?添加和响应(使用status(HttpStatus.NOT_FOUND));a可以帮助您添加和响应(with status(HttpStatus.NOT_FOUND))提供一个带有已定义http状态代码的ClientHTTPResponse。这意味着,调用response=template.exchange(url,DELETE,null,MyResponseModel.class,id);返回响应而不是RESTClientException restTemplate绑定到您的mockServer。通过查看restTemplate的源代码,您可以看到当在响应中遇到4xx代码时,会抛出一个特定的RestClientException。因此,模拟服务器的4xx响应应该会让你陷入困境。嗨,Alex,我想你是对的。我忘了,我设置了一个自定义的errorHandler,当状态代码为4xx或5xx时,它捕获了这个异常。所以在这个地方不可能发生RestClientException.:-)谢谢你的建议!这救了我一天!这甚至不编译
RestTemplate yourApi;
MockRestServiceServer server = MockRestServiceServer.createServer(yourApi);
server.expect(requestTo("http://..."))
.andRespond((response) -> { throw new ResourceAccessException(
new ConnectException("Connection reset")); });
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);
@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());
}