我有简单的服务
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);