问题描述
我正在将Qurkus与Microprofile Fault Tolerance
结合使用,以对JDBC连接(Dremio)实施全额收费。
我已经实现了类似的东西:
class Repository {
private final DataSource dataSource; //initialized on constructor
Collection<String> getData() exception sqlException {
try (var conn = dataSource.getConnection();
var stmt = conn.createStatement();
var rs = stmt.executeQuery(sql)) {
var result = new ArrayList<String>();
while (rs.next()) {
result.add(rs.getString("data"));
}
return result;
} catch(sqlException e) {
//log and throw custom exception
}
}
}
class Service {
@Inject
Repository repo;
public Collection<String> callService() {
//other code that dosen't require retries
try {
var res = getData();
} catch (Exception e) {
//log exception
throw new CustomException(e);
}
return res;
}
@Retry()
private Collection<String> getData() throw Exception {
return repo.getData();
}
}
现在,我正在尝试使用单元测试对重试进行测试。我没有找到任何与Microprofile Fault Tolerance
相关的文档。
@QuarkusTest
class ServiceTest {
@Inject
Service service;
@InjectMock
Repository repository;
@Test
void shouldHandleretrywhenErrorOccursDuringQueryData() throws Exception {
ArrayList<String> expectedResult = Lists.newArrayList("1","2");
when(repository.getData())
.thenThrow(new RuntimeException("Runtime Exception"))
.thenReturn(expectedResult);
Collection<String> executionResult = service.callService();
assertIterableEquals(expectedResult,executionResult);
}
}
我的期望是,数据在一次重试后返回(对getData
的第一次调用返回错误)。而是仅返回错误。
解决方法
不幸的是,不能将Mocks与Fault Tolerance注释一起使用,因为Mockito有效地覆盖了有关原始方法的所有内容,包括@Retry
注释。您可以通过将@Retry
注释移到您不嘲笑的东西(Service.callService()
方法)上来解决此问题,以便改用callService
方法,然后再次尝试,对存储库的调用将通过。