[英]Best practices for verifying recursive method calls with Mockito
考虑以下示例类:
public class Processor {
private final Dependency dependency;
public Processor(Dependency dependency) {
this.dependency = dependency;
}
public void processUsers(List<Integer> userIds, int attempt) {
if (attempt == 0) {
//log initial processing
} else if (attempt > 0 && attempt < 5) {
//log retry processing
} else {
//log processing limit exceeded
return;
}
List<Integer> failedIds = new ArrayList<Integer>();
for (Integer userId : userIds) {
try {
processUser(userId);
} catch (Exception ex) {
//logging
failedIds.add(userId);
}
}
if (failedIds.isEmpty()) {
//log ok
} else {
processUsers(failedIds, attempt + 1);
}
}
public void processUser(Integer userId) throws Exception{
//dependency can throw exception
dependency.call();
}
}
我想验证抛出异常时方法processUsers
自行调用。 这是我的测试:
public class ProcessorTest {
@Test
public void processShouldCallItselfWithFailedSublistWhenProcessingFails(){
Dependency dependency = mock(Dependency.class);
when(dependency.call()).thenThrow(Exception.class);
Processor processor = new Processor(dependency);
processor.processUsers(Arrays.asList(new Integer[]{1,2,3}), 0);
//need to verify processor will call #processUsers recursively
//because the dependency thrown Exception, how?
}
}
在某些情况下,递归地验证该方法的最佳实践是什么?
我正在使用TestNG + Mockito和称为JAVA
冗长语言
您可以验证dependency.call()
被调用的次数。 这将告诉您重试有效-仅按呼叫数即可:
@Test
public void processShouldCallItselfWithFailedSublistWhenProcessingFails() {
Dependency dependency = mock(Dependency.class);
when(dependency.call()).thenReturn(1, 2).thenThrow(Exception.class).
thenReturn(4);
Processor processor = new Processor(dependency);
processor.processUsers(Arrays.asList(new Integer[]{1, 2, 3}), 0);
verify(dependency, times(4)).call();
}
这将告诉您,重试最终因太多异常而失败:
@Test
public void processShouldFailAfterTooManyRetries() {
Dependency dependency = mock(Dependency.class);
when(dependency.call()).thenThrow(Exception.class);
Processor processor = new Processor(dependency);
final List<Integer> userIds = Arrays.asList(new Integer[]{1, 2, 3});
final int expectedRetries = 5;
processor.processUsers(userIds, 0);
verify(dependency, times(expectedRetries * userIds.size())).call();
}
如果对依赖项的调用实际上使用了userId,则实际上可以检查是否对期望的所有dependency.call(int userId)
调用都进行了dependency.call(int userId)
。 这将告诉您所有这些都经过足够的重试:
@Test
public void processShouldCallItselfWithFailedSublistWhenProcessingFails() {
Dependency dependency = mock(Dependency.class);
when(dependency.call(anyInt())).
thenReturn(1, 2).thenThrow(Exception.class).thenReturn(4);
Processor processor = new Processor(dependency);
processor.processUsers(Arrays.asList(new Integer[]{1, 2, 3}), 0);
verify(dependency).call(1);
verify(dependency).call(2);
verify(dependency, times(2)).call(3);
}
@Test
public void processShouldFailAfterTooManyRetries() {
Dependency dependency = mock(Dependency.class);
when(dependency.call(anyInt())).thenThrow(Exception.class);
Processor processor = new Processor(dependency);
final List<Integer> userIds = Arrays.asList(new Integer[]{1, 2, 3});
final int expectedRetries = 5;
processor.processUsers(userIds, 0);
for (Integer userId : userIds) {
verify(dependency, times(expectedRetries)).call(userId);
}
}
不确定最佳做法,但是可以通过验证方法的调用次数来实现最佳做法
int invocationCount = 5; // Or any other desired number
verify(processor,times(invocationCount)).processUsers();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.