我有一个void方法,该方法创建Foo
类型的对象并更新这些对象列表的每个条目。
当参数传递的列表为空时,它不应创建任何对象,因此不调用类Foo
的任何setter方法。
public static void analyzeList(ArrayList<Something> list) {
for (Something s : list) {
Foo f = new Foo();
f.setSomething(someMethod1(f));
f.setSomething2(someMethod2(f));
s.setFoo(f);
}
}
因此,我试图使用Mockito来检查方法analyzeList(ArrayList<Something> list)
没有调用类Foo
的任何setter方法,但是这样做很麻烦,因为我从未使用过Mockito以前。
我写了这个测试:
@Test
public void shouldNotCallSettersWhenListIsEmpty() {
Foo fooMocked = mock(Foo.class);
FooLogic.analyzeList(emptyList);
Mockito.verify(fooMocked, times(0)).setSomething(anyInt());
}
该测试通过,应该通过。但是,当我将times(0)
更改为times(1)
时,由于列表为空,因此测试一直通过并且不应该通过。
我在这里做什么错了?
答案 0 :(得分:3)
您在测试中拥有的Foo
对象与在Foo
中创建的analyzeList
对象是不同的。每次在代码中创建一个 new Foo 对象。
即使您传递了非空列表,Mockito.verify(fooMocked, times(0)).setSomething(anyInt());
也将通过,因为您没有在模拟的Foo实例上调用任何方法。
但是您说通过将times(0)
更改为times(1)
,测试仍然可以通过。但是测试应该失败(您可以重新检查一下)
在当前设置下,您无法在创建的Foo f
实例 1 上验证任何内容。如果您传递的列表具有模拟setFoo
对象,您仍然可以验证在Something
上进行的Something
调用。
1 ,除非您使用Powermockito或允许您在代码中模拟new
对象创建的东西。
答案 1 :(得分:0)
根据您的情况,
我喜欢用
InOrder
功能;
特别是
InOrder.verifyNoMoreInteractions()
方法。
这里是一个例子:
import static org.mockito.Mockito.inOrder;
import org.mockito.InOrder;
@Test
public void shouldNotCallSettersWhenListIsEmpty() {
Foo fooMocked = mock(Foo.class);
InOrder inOrderVariable = inOrder(fooMocked);
FooLogic.analyzeList(emptyList);
//Mockito.verify(fooMocked, times(0)).setSomething(anyInt());
// Note: added example verify statement.
inOrderVariable.verify(fooMocked).someMethod(paramaters)
inOrderVariable.verifyNoMoreInteractions();
}