我在与Mockito框架方面苦苦挣扎:
我有一个特定类型的Set
,我想验证其中是否有任何对象称为特定方法。这是我的代码:
@Mock
private Set<MyType> myTypes = (Set<MyType>) mock(Set.class);
@Before
public void setUp() throws Exception{
TestObject testObject = spy(new TestObject());
for(int i = 0; i < 4; i++){
MyType mT = mock(MyType.class);
mT.setName("Name"+i);
myTypes.add(mT);
}
testObject.setMyTypesSet(myTypes);
}
@Test
public void myTypeSet_Test(){
//call method which calls "getName()" for each element in the set
testObject.myTypeSet();
//HERE IS MY STRUGGLE
verify(myType, times(3)).getName();
}
所以myTypes
对象有一个名为getName()
的方法。我想测试,如果方法getName()
在我测试的方法中被调用了 3 次。我不能写verify(myTypes, times(3)).getName()
,因为Set
没有方法getName()
.我希望我说得很清楚。
你不需要在这里嘲笑Set
;有一个充满模拟的常规Set
应该就足够了:
private Set<MyType> myTypes = new HashSet<>();
然后
for(MyType myType : myTypes) {
verify(myType, times(3)).getName();
}
这是假设您实际上为每个 set 元素调用getName()
3 次。如果不是这种情况,并且您只是为每个调用一次,那么它将times(1)
您可以简单地对 Set 的每个模拟元素调用验证:
for (MyType myType : myTypes) {
verify(myType, times(3))
.getName();
}
但这不适用于实际代码,因为myTypes
被定义为Mock
:
@Mock
private Set<MyType> myTypes = (Set<MyType>) mock(Set.class);
而且你没有为它记录任何行为。
因此,您永远无法迭代添加的元素,因为元素永远不会添加到Set
中,因为您这样做:
MyType mT = Mockito.mock(MyType.class);
mT.setName("Name" + i);
myTypes.add(mT);
事实上,myTypes
不必是嘲笑。
将其声明为纯对象:
private Set<MyType> myTypes = new HashSet<>();
您也不需要监视被测对象。
您要验证invocation of mocks
,而不是对被测对象的调用。
所以你也可以替换:
TestObject testObject = Mockito.spy(new TestObject());
由:
TestObject testObject = new TestObject();
请注意,间谍活动不是一种好的做法,而是一种解决方法。因此,请尽可能避免这种情况,最重要的是您不需要它!
应该没问题。
验证 getName 方法是否在每个对象上被调用了 3 次
for(MyType myType : myTypes) {
verify(myType, times(3)).getName();
}
验证 getName 方法是否在任何对象上总共被调用了 3 次
public class MyTypeTest {
@Mock private Set<MyType> myTypes = new HashSet<>();
@Before
public void setUp() throws Exception{
TestObject testObject = spy(new TestObject());
for(int i = 0; i < 4; i++){
MyType mT = Mockito.mock(MyType.class);
mT.setName("Name"+i);
myTypes.add(mT);
}
testObject.setMyTypesSet(myTypes);
}
@Test
public void myTypeSet_Test(){
//call method which calls "getName()" for each element in the set
testObject.myTypeSet();
int numberOfCalls = 0;
for(MyType myTypeMock : myTypes) {
Collection<Invocation> invocations = Mockito.mockingDetails(myTypeMock).getInvocations();
numberOfCalls += invocations.size();
}
assertEquals(3, numberOfCalls)
}
}
class MyType {
private String name;
public void setName(String n) { name = n;}
public String getName() {return name};
}