2013-08-29 62 views
17

創建嘲笑名單我想創建一個嘲笑列表來測試下面的代碼:通過的Mockito

for (String history : list) { 
     //code here 
    } 

這是我實現:

public static List<String> createList(List<String> mockedList) { 

    List<String> list = mock(List.class); 
    Iterator<String> iterHistory = mock(Iterator.class); 

    OngoingStubbing<Boolean> osBoolean = when(iterHistory.hasNext()); 
    OngoingStubbing<String> osHistory = when(iterHistory.next()); 

    for (String history : mockedList) { 

     osBoolean = osBoolean.thenReturn(true); 
     osHistory = osHistory.thenReturn(history); 
    } 
    osBoolean = osBoolean.thenReturn(false); 

    when(list.iterator()).thenReturn(iterHistory); 

    return list; 
} 

但試運行時,它拋出的線路異常:

OngoingStubbing<DyActionHistory> osHistory = when(iterHistory.next()); 

的詳細信息:

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here: 
-> at org.powermock.api.mockito.PowerMockito.when(PowerMockito.java:495) 

E.g. thenReturn() may be missing. 
Examples of correct stubbing: 
    when(mock.isOk()).thenReturn(true); 
    when(mock.isOk()).thenThrow(exception); 
    doThrow(exception).when(mock).someVoidMethod(); 
Hints: 
1. missing thenReturn() 
2. you are trying to stub a final method, you naughty developer! 

我該如何解決?謝謝

+1

可能重複[的Mockito:嘲諷,這將在for循環中被循環一個ArrayList(HTTP://計算器。 com/questions/18483176/mockito-mocking-an-arraylist-that-will-be-loop-in-a-for-loop) –

回答

19

好的,這是一件壞事要做。不要嘲笑一個列表;相反,模擬列表中的單個對象。有關如何操作,請參閱Mockito: mocking an arraylist that will be looped in a for loop

另外,你爲什麼使用PowerMock?你似乎沒有做任何需要PowerMock的事情。

但是,問題的真正原因是您在完成存根之前在兩個不同的對象上使用了when。當你打電話給when,並提供你正在嘗試存根的方法調用時,那麼你在Mockito或PowerMock中做的下一件事是指定調用該方法時發生的情況 - 即執行thenReturn部分。在撥打when之前,每撥打一個電話when必須緊跟一個且只有一個電話thenReturn,然後再撥打when。您撥打了when兩個電話,但未撥打thenReturn - 這是您的錯誤。

+1

但是如果你真的需要,你會如何嘲笑一個列表? – BlueShark

+2

你爲什麼真的必須?總是做錯事情。這就像問「如果你真的必須用錘子來驅動螺絲釘」。這是錯誤的方法 - 工作的錯誤工具。 –

+0

你如何返回一個正常的列表,然後與嘲笑的項目裏面? – BlueShark

2

我們可以爲foreach循環正確地模擬列表。請找到下面的代碼片段和解釋。

這是我實際的類方法,我想通過嘲笑列表創建測試用例。 this.nameList是一個列表對象。

public void setOptions(){ 
    // .... 
    for (String str : this.nameList) { 
     str = "-"+str; 
    } 
    // .... 
} 

foreach循環內部工作在迭代器上,所以在這裏我們編寫了迭代器的模擬器。 Mockito框架可以通過使用Mockito.when().thenReturn()返回特定方法調用的值對,即在hasNext()上我們傳遞第一個true和第二個調用false,這樣我們的循環將只繼續兩次。在next()我們只是返回實際的回報值。

@Test 
public void testSetOptions(){ 
    // ... 
    Iterator<SampleFilter> itr = Mockito.mock(Iterator.class); 
    Mockito.when(itr.hasNext()).thenReturn(true, false); 
    Mockito.when(itr.next()).thenReturn(Mockito.any(String.class); 

    List mockNameList = Mockito.mock(List.class); 
    Mockito.when(mockNameList.iterator()).thenReturn(itr); 
    // ... 
} 

這樣,我們才能避免發送實際列表通過使用列表的模擬測試。

4

當嘲諷名單和迭代他們打交道,我總是用這樣的:的

@Spy 
private List<Object> parts = new ArrayList<>();