我是Mockito的新手。我试图在我的测试类中使用Mockito的Answer
接口来测试getAllFoo()
方法的所有分支。我希望isFooComplete()
在调用前2次返回false
,然后第三次返回true
,以便actualFoo
最后包含2个Foo
个对象测试。
问题在于,我在getAllFoo()
上调用service
的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 :(得分:1)
在您的示例中,您没有递增计数器。因此,您的计数器始终为0.因此,在返回并将条件更改为counter >= 2
之前when(fooService.isFooComplete()).thenReturn(true, true, false)
应该执行此操作。
但看起来你正在本答案中实现你的FooService逻辑的一部分。我认为{{1}}可能是更好的选择。
答案 1 :(得分:0)
你有一个无限循环。 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();
}