2017-12-18 359 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

謝謝!我會嘗試,但看起來合法! –

相關問題