Mockito中的连续调用测试



我有简单的服务

package net.betlista;
import java.util.List;
public class MyServiceImpl implements MyService {
    MyDao dao;
    public void saveAll(final List<Integer> list) {
        for (final int i : list) {
            dao.save(i);
        }
    }
    void setDao(final MyDao dao) {
        this.dao = dao;
    }
}

和DAO

package net.betlista;
public class MyDaoImpl implements MyDao {
    public void save(final Integer i) {
        // do nothing, ok for tests
    }
}

我想用Mockito测试一下,当我调用service.saveAll()时,会为列表中的所有实例调用save()调用:

package net.betlista;
import java.util.LinkedList;
import java.util.List;
import org.junit.Test;
import org.mockito.InOrder;
import org.mockito.Mockito;
public class MyServiceTest {
    @Test
    public void test() {
        final MyDao daoMock = Mockito.mock(MyDao.class);
        final MyServiceImpl service = new MyServiceImpl();
        service.setDao(daoMock);
        final List<Integer> list = new LinkedList<Integer>();
        list.add(1);
        list.add(2);
        service.saveAll(list);
        // not working, it's ok, should fail
        //        Mockito.verify(daoMock).save(Matchers.eq(1));
        //        Mockito.verify(daoMock).save(Matchers.eq(1));
        final InOrder inOrder = Mockito.inOrder(daoMock);
        inOrder.verify(daoMock).save(1);
        inOrder.verify(daoMock).save(1); // change 1 to 2 to fix test
        Mockito.verify(daoMock);
    }
}

注释部分不起作用=它通过了,但应该失败。

使用InOrder是有效的,但事实上我对顺序不感兴趣(例如,如果使用set而不是list,则顺序是未知的)。

有什么想法吗,或者我只是想做一些毫无意义的事情?

最好的方法是使用ArgumentCaptor

service.saveAll(list);
ArgumentCaptor<Integer> values = ArgumentCaptor.forClass(Integer.class);
verify(daoMock, times(list.size())).save(values.capture());
assertEquals(list, values.getAllValues());

ArgumentCaptor允许您访问曾经传递给此方法的所有值。因此,不必担心这种方法是否被称为"额外"次数;并且在相同值在原始列表中出现两次的情况下没有问题。

我想用Mockito测试一下,当我调用service.saveAll()时,会为列表中的所有实例调用save()调用

好的,那么这个怎么样:

service.saveAll(list);
for (int i:list)
{
    Mockito.verify(daoMock).save(Matchers.eq(i));
}

我不完全确定你为什么认为注释掉的行应该失败,但我猜这是因为你想确保它只被调用一次?如果是这样,那么它之所以通过它,是因为它只被调用过一次,然而,您的测试代码正在两次验证它是否只被调用了一次,这没有多大用处。上面的代码将验证是否为列表中的每个项调用了保存方法一次(且仅调用一次)。

 Mockito.verify(daoMock, Mockito.times(2)).save(Matchers.eq(1));

由于您正在验证相同的值,请使用times()

然而,测试是否有您想要的调用数量的更好方法是使用verifyNoMoreInteractions

所以测试应该是这样的:

 verify(daoMock).save(1);
 verify(daoMock).save(2);
 verifyNoMoreInteractions(daoMock);

相关内容

  • 没有找到相关文章

最新更新