rest - 使用 MockRestServiceServer 时无法精确测试服务调用次数
问题描述
我正在为服务调用编写一些重试逻辑,并尝试在单元测试中测试 Rest Template 是否尝试命中服务一定次数。我正在使用以下代码来执行测试。
MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
mockServer.expect(ExpectedCount.times(5), method(HttpMethod.GET))
.andRespond(withServerError());
service.call();
我将重试逻辑设置为仅进行两次尝试。上面的测试代码要求它发生五次,但测试总是通过。事实上,我可以让这个测试失败的唯一方法是将预期计数设置为 1(任何小于实际调用次数的值)。ExpectedCount.min
当我使用或ExpectedCount.between
只有当实际调用超出预期时测试才会失败,也会出现同样的问题。
我需要能够测试确切数量的服务调用,最好不使用 Mockito。
解决方案
这是最终对我有用的方法,最大尝试次数为 4:
MockRestServiceServer server;
@Before
public void setUp() {
server = MockRestServiceServer.bindTo(restTemplate).build();
}
@After
public void serverVerify() {
server.verify();
}
@Test
public void doWork_retryThenSuccess() throws Exception {
final String responseBody = "<some valid response JSON>";
final String url = BASE_URL + "/doWork";
server.expect(requestTo(url))
.andExpect(MockRestRequestMatchers.method(HttpMethod.POST))
.andRespond(ExceptionResponseCreator.withException(new SocketTimeoutException("first")));
server.expect(requestTo(url))
.andExpect(MockRestRequestMatchers.method(HttpMethod.POST))
.andRespond(ExceptionResponseCreator.withException(new IOException("second")));
server.expect(requestTo(url))
.andExpect(MockRestRequestMatchers.method(HttpMethod.POST))
.andRespond(ExceptionResponseCreator.withException(new RemoteAccessException("third")));
server.expect(requestTo(url))
.andExpect(MockRestRequestMatchers.method(HttpMethod.POST))
.andRespond(withSuccess(responseBody, MediaType.APPLICATION_JSON));
final MyResponseClass response = myService.call();
assertThat(response, notNullValue());
// other asserts here...
}
我们被限制使用 Spring Test 5.0.10,它没有MockRequestResponseCreators.withException()
(方法是在 5.2.2 中添加的)。借用 Spring 5.2.7 代码,这很好用:
package com.company.test;
import java.io.IOException;
import org.springframework.remoting.RemoteAccessException;
import org.springframework.test.web.client.ResponseCreator;
import org.springframework.test.web.client.response.MockRestResponseCreators;
public class ExceptionResponseCreator extends MockRestResponseCreators {
public static ResponseCreator withException(IOException ex) {
return request -> { throw ex; };
}
public static ResponseCreator withException(RemoteAccessException ex) {
return request -> { throw ex; };
}
}
推荐阅读
- python - 应该接触的匀称多边形不
- leaflet - 如何将 800k 点作为 MVT 处理
- ios - MacOS 中挂载的远程目录经常被卸载
- c# - 有条件地等待任务
- sql-server - 在 SQL Server 中生成随机值
- java - 滚动时使用 FirebaseListAdapter 和 ListView 重复数据
- python - 在 Keras、Tensorflow 上 CPU 使用率超过 GPU 使用率
- python - 交换二维数组中的多个索引
- python - 使用 Pandas 变换计数不同
- python - 具有 2 个或更多同名外键的 Python/Django 模型