2017-12-18 363 views
1

我在与的Mockito框架斗争:的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()。我希望我说清楚。

回答

0

你可以简单地调用验证设置的每个嘲笑元素:

for (MyType myType : myTypes) { 
    verify(myType, times(3)) 
    .getName(); 
} 

但这因为myTypes被定义为Mock不会与实际的代码工作:

@Mock 
private Set<MyType> myTypes = (Set<MyType>) mock(Set.class); 

而且你没有记录任何行为吧。

MyType mT = Mockito.mock(MyType.class); 
mT.setName("Name" + i); 
myTypes.add(mT); 

其实myTypes不必是一个模拟:
所以当你做,你永远无法重复上添加元素的元素永远不会在Set添加。
声明它作为一个普通的对象:

private Set<MyType> myTypes = new HashSet<>(); 

你并不需要或者窥探被测对象。
你想验证invocation of mocks,而不是被测对象的调用。

所以,你也可以更换:

TestObject testObject = Mockito.spy(new TestObject()); 

由:

TestObject testObject = new TestObject(); 

注意,间谍是不是一个好做法,但解决方法。所以尽可能地避免,因为你不需要它!

它应该没问题。

+0

感谢您的解释!我会尝试代码并给出评论,但似乎是逻辑! –

0

要验证的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}; 
} 
+0

我想这足够了解它被称为总共3次。我会尝试这个并给出反馈。谢谢! :) –

+0

我更新了我的答案,也许这个其他方式更好 – Bentaye

1

您这里不需要模拟Set;具有正Set充满嘲笑应该是足够了:

private Set<MyType> myTypes = new HashSet<>(); 

然后

for(MyType myType : myTypes) { 
    verify(myType, times(3)).getName(); 
} 

这是假设你居然叫getName() 3次,每次元素。如果是这种情况并非如此,你只是调用它每进行一次,这将是times(1)代替

+0

谢谢!我会尝试,但看起来合法! –

相关问题