Mockito 验证 lambda 被调用 n 次
Mockito verify lambda is called n-times
我需要测试一个 lambda 函数是否被服务实例调用了 n 次。
我有一个与存储库交互的服务 class,当从存储库检索数据时发生错误时,服务应该重试,直到达到最大重试次数,所以我实现如下:
interface Repository {
Collection<String> getData();
}
public class RetryHelper<T> {
private Integer retries;
public RetryHelper(Integer retries) {
this.retries = retries;
}
public interface Operation<T> {
T doIt() throws Exception;
}
public T doWithRetry(Operation<T> operation) throws Exception {
int remainRetries = retries;
do {
try {
return operation.doIt();
} catch (Exception e) {
if (remainRetries == 0) {
throw e;
}
//TODO: wait before retry
remainRetries--;
}
} while (true);
}
}
class Service {
@Inject
Repository repo;
private final RetryHelper<Collection<String>> retryHelper;
public Collection<String> callService() {
try {
Collection<String> res = retryHelper.doWithRetry(() ->
repo.getData());
return res;
} catch (Exception e) {
throw (CustomException) e;
}
}
}
我需要使用 Mockito 进行测试,当发生错误时 repo.getData()
被调用了 n 次。我可以更改 Service
代码和 RetryHelper
,因此我愿意接受建议。
我已经尝试按照教程和文档实施测试:
public class ServiceTest {
@Inject
Service service;
@InjectMock
Repository repository;
@InjectMock
RetryHelper<Collection<String>> retryHelper;
@Captor
ArgumentCaptor<RetryHelper.Operation<Collection<String>>> operation;
@BeforeEach
void init_mocks() {
MockitoAnnotations.openMocks(this);
}
@Test
void shouldRetryIfDataQueryFailsForNonFatalError() throws Exception {
when(repository.getData())
.thenThrow(new RuntimeException("Runtime Exception"));
service.callService();
verify(retryHelper).doWithRetry(operation.capture());
verify(repository, times(2)).getData();
}
}
测试失败并显示 getData()
从未被调用的消息。
我终于在不使用 Captor
的情况下找到了解决方案
public class ServiceTest {
@Inject
Service service;
@InjectMock
Repository repository;
@Inject
RetryHelper<Collection<String>> retryHelper;
@Test
void shouldRetryIfDataQueryFailsForNonFatalError() throws Exception {
when(repository.getData())
.thenThrow(new RuntimeException("Runtime Exception"));
try {
service.callService();
} catch(Exception e) {
verify(repository, times(2)).getData();
}
}
}
我需要测试一个 lambda 函数是否被服务实例调用了 n 次。
我有一个与存储库交互的服务 class,当从存储库检索数据时发生错误时,服务应该重试,直到达到最大重试次数,所以我实现如下:
interface Repository {
Collection<String> getData();
}
public class RetryHelper<T> {
private Integer retries;
public RetryHelper(Integer retries) {
this.retries = retries;
}
public interface Operation<T> {
T doIt() throws Exception;
}
public T doWithRetry(Operation<T> operation) throws Exception {
int remainRetries = retries;
do {
try {
return operation.doIt();
} catch (Exception e) {
if (remainRetries == 0) {
throw e;
}
//TODO: wait before retry
remainRetries--;
}
} while (true);
}
}
class Service {
@Inject
Repository repo;
private final RetryHelper<Collection<String>> retryHelper;
public Collection<String> callService() {
try {
Collection<String> res = retryHelper.doWithRetry(() ->
repo.getData());
return res;
} catch (Exception e) {
throw (CustomException) e;
}
}
}
我需要使用 Mockito 进行测试,当发生错误时 repo.getData()
被调用了 n 次。我可以更改 Service
代码和 RetryHelper
,因此我愿意接受建议。
我已经尝试按照教程和文档实施测试:
public class ServiceTest {
@Inject
Service service;
@InjectMock
Repository repository;
@InjectMock
RetryHelper<Collection<String>> retryHelper;
@Captor
ArgumentCaptor<RetryHelper.Operation<Collection<String>>> operation;
@BeforeEach
void init_mocks() {
MockitoAnnotations.openMocks(this);
}
@Test
void shouldRetryIfDataQueryFailsForNonFatalError() throws Exception {
when(repository.getData())
.thenThrow(new RuntimeException("Runtime Exception"));
service.callService();
verify(retryHelper).doWithRetry(operation.capture());
verify(repository, times(2)).getData();
}
}
测试失败并显示 getData()
从未被调用的消息。
我终于在不使用 Captor
public class ServiceTest {
@Inject
Service service;
@InjectMock
Repository repository;
@Inject
RetryHelper<Collection<String>> retryHelper;
@Test
void shouldRetryIfDataQueryFailsForNonFatalError() throws Exception {
when(repository.getData())
.thenThrow(new RuntimeException("Runtime Exception"));
try {
service.callService();
} catch(Exception e) {
verify(repository, times(2)).getData();
}
}
}