实现Mockito的Answer接口来测试方法的所有分支

时间:2017-02-26 18:29:50

标签: java junit mockito

我是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());
    }
}

2 个答案:

答案 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();
}