簡體   English   中英

通過mockito創建一個模擬列表

[英]Create a mocked list by 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!

我該如何解決? 謝謝

好的,這是一件壞事。 不要嘲笑一個清單; 相反,模擬列表中的各個對象。 請參閱Mockito:嘲笑一個arraylist,它將在for循環中循環以獲取如何執行此操作。

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

但是你的問題的真正原因是,你正在使用when在兩個不同的對象,在完成之前存根。 當你調用when ,並提供你試圖存根的方法調用時,你在Mockito或PowerMock中做的下一件事就是指定在調用該方法時會發生什么 - 也就是說,執行thenReturn部分。 每次調用when必須跟隨一次且只有一次調用thenReturn ,然后再調用when 你讓兩個調用when無需調用thenReturn -這是你的錯誤。

在處理模擬列表並迭代它們時,我總是使用類似的東西:

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

我們可以為foreach循環正確地模擬列表。 請在下面找到代碼段和說明。

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

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

foreach循環內部在迭代器上工作,所以這里我們創建了iterator的mock。 Mockito框架具有通過使用Mockito.when().thenReturn()返回特定方法調用的值對的功能,即在hasNext()我們傳遞1st 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);
    // ...
}

通過這種方式我們可以避免使用list的mock來發送實際列表進行測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM