簡體   English   中英

如何使用mockito間諜進行懶惰評估?

[英]how to use mockito spy for lazy evaluation?

我想用mockito間諜。

當我以下列兩種方式設置返回值時:

when(imagesSorterSpy.sortImages(imagesAsInsertionOrder, user)).thenReturn(imagesSorterSpy.sortImages(imagesAsInsertionOrder, user, fakeNowDate));

doReturn(imagesSorterSpy.sortImages(imagesAsInsertionOrder, user, fakeNowDate)).when(imagesSorterSpy).sortImages(imagesAsInsertionOrder, user);

我看到正在急切地評估返回值

執行此“設置”行時的含義。

我如何強迫間諜只根據需要評估回報價值?

表示滿足“when”條件時的含義。

更新

感謝@RobbyCornelissen我試過這段代碼:

    when(imagesSorterSpy.sortImages(imagesAsInsertionOrder, user)).thenAnswer(new Answer() {
        public Object answer(InvocationOnMock invocation) {
            Object[] args = invocation.getArguments();
            ImagesSorter mock = (ImagesSorter)invocation.getMock();
            return mock.sortImages((List<Image>)args[0], (UserInfo)args[1], fakeNowDate);
        }
    });

但它沒有幫助:

1)立即調用“when”表達式。 (不想要的)

2)最終回調不是調用。

首先讓我對部分嘲諷發出警告,因為這就是代碼實際上正在做的事情,這是錯誤的設計明智。 使用策略模式來組成測試對象的行為可能更相關。 Mockito團隊(包括我)強烈建議盡可能遠離部分嘲笑。

編輯 :我不知道代碼,我ImagesSorter知道哪個組件正在測試,但從我收集的是一個負責排序圖像的類型,讓我們稱之為ImagesSorter

  1. 因此,第一種情況ImagesSorter是測試主題的依賴關系,所以在這種情況下,只需ImagesSorter 模擬 ImagesSorter

  2. 但是,如果它是ImagesSorter本身正在測試中,並且對該類的特殊方法進行存根稱為部分模擬,則它是完全錯誤的。 它公開了測試中生產代碼的內部。 所以有幾種解決方案。

    1. 正如答案中顯示的代碼片段顯示的是fakeDate ,其中一個解決方案是不使用new Date()等代碼並編寫一個簡單的類TimeSource其唯一的責任是提供日期。 在測試中,這個TimeSOurce可以被覆蓋。

      一個更簡單的解決方案是使用JodaTime,因為它提供了內置的這個功能。

    2. 如果測試范圍超出了更改日期的范圍,那么ImagesSorter可能需要一種配置其他對象的方法。 可以通過番石榴的緩存構建器找到有關如何執行此操作的靈感。 如果配置很簡單,那么一個簡單的構造函數就可以做到。

      這可能看起來像:

       class ImagesSorter { ImagesSorterAlso algo; ImagesSorter(ImagesSorterAlgo algo) { this.algo = algo; } Iterable sortImages(...) { algo.sort(...); } } interface ImagesSorterAlgo { Iterable sort(...); } 

現在關於你的問題:

1)立即調用“when”表達式。 (不想要的)

預計imagesSorterSpy是間諜,所以默認情況下它會調用真實代碼。 相反,您應該使用備用API,與@RobbyCornelissen顯示的相同。

doAnswer(sortWithFakeDate()).when(imagesSorterSpy).sortImages(imagesAsInsertionOrder, user);

// with BDD aliases (BDDMockito) which I personnaly finds better
willAnswer(sortWithFakeDate()).given(imagesSorterSpy).sortImages(imagesAsInsertionOrder, user);
will(sortWithFakeDate()).given(imagesSorterSpy).sortImages(imagesAsInsertionOrder, user);

sortWithFakeDate()將返回一個返回答案的靜態工廠方法,因此代碼讀取得很好,並且可能在其他地方重用。

2)最終回調不是調用。

這個問題很可能是由於不相等的論點造成的。 您可能需要檢查equals方法。 或者使用any()匹配器放松存根。

我不知道您正在使用的參數和類的類型,因此我無法提供完整的示例,但您可以使用Answer<T>接口使用回調來存根:

Mockito.doAnswer(new Answer() {
    Object answer(InvocationOnMock invocation) {
         ImagesSorter mock = (ImagesSorter) invocation.getMock();
         Object[] args = invocation.getArguments();

         return mock.sortImages((List<Image>) args[0], (UserInfo) args[1],
                 fakeNowDate);
    }
}).when(imagesSorterSpy).sortImages(imagesAsInsertionOrder, user);

暫無
暫無

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

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