我有简单的服务
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,则命令未知)。
任何想法,或者我只是想做一些毫无意义的事情?
答案 0 :(得分:4)
执行此操作的最佳方法是使用ArgumentCaptor
。
service.saveAll(list);
ArgumentCaptor<Integer> values = ArgumentCaptor.forClass(Integer.class);
verify(daoMock, times(list.size())).save(values.capture());
assertEquals(list, values.getAllValues());
ArgumentCaptor
使您可以访问传递给此方法的所有值。所以没有必要担心这种方法是否被称为“额外”时间;并且在原始列表中出现两次相同值的情况下没有问题。
答案 1 :(得分:2)
我想用Mockito测试当我调用service.saveAll()时,为列表中的所有实例调用save()调用
好的,那怎么样:
service.saveAll(list);
for (int i:list)
{
Mockito.verify(daoMock).save(Matchers.eq(i));
}
我不完全确定为什么你认为注释掉的行会失败,但我猜它是因为你想确保它只调用一次?如果是这样,那么它传递它的原因是因为它只被调用过一次,但是,你的测试代码正在验证两次它只被调用一次并没有多大用处。上面的代码将验证是否为列表中的每个项调用了save方法一次(并且只调用一次)。
答案 2 :(得分:1)
Mockito.verify(daoMock, Mockito.times(2)).save(Matchers.eq(1));
由于您要验证相同的值,请使用times()
然而,更好的方法是测试你想要的调用数量正是使用verifyNoMoreInteractions
所以测试会是这样的:
verify(daoMock).save(1);
verify(daoMock).save(2);
verifyNoMoreInteractions(daoMock);