我是Mockito的新手。我正在尝试在我的测试类中使用 Mockito 的Answer
接口,以测试getAllFoo()
方法的所有分支。我希望isFooComplete()
false
前 2 次调用它时返回,然后第三次返回true
,以便actualFoo
在测试结束时包含 2 个Foo
对象。
问题是,在我在service
上调用getAllFoo()
的 for 循环中,第一次返回false
,然后测试陷入无限循环(正如您期望查看getAllFoo()
方法实现一样)。
如何修改此测试,以便getAllFoo()
返回false
两次,然后返回true
并终止循环?
服务等级:
public class ServiceImpl {
@Autowired
FooService fooService;
public Collection<Foo> getAllFoo() {
Collection<Foo> allFoo = new ArrayList<>();
boolean complete = fooService.isFooComplete();
boolean available = fooService.isFooAvailable();
while (!complete && available) {
Foo foo = fooService.getAvailableFoo();
allFoo.add(foo);
}
return allFoo;
}
}
测试类:
public class ServiceImplTest {
@InjectMocks
ServiceImpl service = new ServiceImpl();
@Mock
FooService fooService;
class MyAnswer implements Answer<Boolean> {
int counter = 0;
@Override
public Boolean answer(InvocationOnMock inovation)
throws Throwable {
return (counter++ > 2) ? Boolean.TRUE : Boolean.FALSE;
}
}
@Test
public void testGetAllFoo() {
MyAnswer myAnswer = new MyAnswer();
MockFoo mockFoo = new MockFoo();
when(fooService.isFooComplete()).thenAnswer(myAnswer);
//when(fooService.isFooComplete()).thenReturn(false, false, true);
when(fooService.isFooAvailable()).thenReturn(true);
when(fooService.getAvailableFoo()).thenReturn(mockFoo);
Collection<Foo> actualFoo = new ArrayList<>();
for (int i = 0; i < 3; i++) {
actualFoo = service.getAllFoo();
}
assertTrue(actualFoo.contains(mockFoo));
assertEquals(2, actualFoo.size());
}
}
在您的示例中,您没有递增计数器。所以你的计数器总是0。因此,在返回并将您的条件更改为counter >= 2
之前counter++
应该这样做。
但看起来你正在这个答案中实现你的部分FooService逻辑。我认为when(fooService.isFooComplete()).thenReturn(true, true, false)
在这里可能是更好的选择。
你有一个无限循环。while (!complete && available)
永远不会完成,因为完整和可用在 while-block 中不会更改。
可能你想这样做:
Collection<Foo> allFoo = new ArrayList<>();
boolean complete = fooService.isFooComplete();
boolean available = fooService.isFooAvailable();
while (!complete && available) {
Foo foo = fooService.getAvailableFoo();
allFoo.add(foo);
complete = fooService.isFooComplete();
available = fooService.isFooAvailable();
}