[英]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
。
因此,第一種情況ImagesSorter
是測試主題的依賴關系,所以在這種情況下,只需ImagesSorter
模擬 ImagesSorter
。
但是,如果它是ImagesSorter
本身正在測試中,並且對該類的特殊方法進行存根稱為部分模擬,則它是完全錯誤的。 它公開了測試中生產代碼的內部。 所以有幾種解決方案。
正如答案中顯示的代碼片段顯示的是fakeDate
,其中一個解決方案是不使用new Date()
等代碼並編寫一個簡單的類TimeSource
其唯一的責任是提供日期。 在測試中,這個TimeSOurce
可以被覆蓋。
一個更簡單的解決方案是使用JodaTime,因為它提供了內置的這個功能。
如果測試范圍超出了更改日期的范圍,那么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.