[英]mocking a method that return generics with wildcard using mockito
我正在使用 mockito 1.9.5。 我有以下代碼:
public class ClassA {
public List<? extends MyInterface> getMyInterfaces() {
return null;
}
public static void testMock() {
List<MyInterface> interfaces = new ArrayList<>();
ClassA classAMock = mock(ClassA.class);
when(classAMock.getMyInterfaces()).thenReturn(interfaces);
}
我收到thenReturn(interfaces)
的編譯錯誤說:
"The method thenReturn(List<capture#1-of ? extends MyInterface>) in the type
OngoingStubbing<List<capture#1-of ? extends MyInterface>> is not applicable for the arguments
(List<MyInterface>)"
但是,當我使用 mockito 的thenAnswer
方法時,我沒有收到錯誤消息。 誰能告訴我這是怎么回事? 為什么在使用thenReturn
方法時會出現錯誤? 當ClassA
由第三方提供且無法修改時,是否有其他方法可以解決此問題?
編輯:從 Mockito 1.10.x 開始,嵌入在類中的泛型類型現在被 Mockito 用於深存根。 IE。
public interface A<T extends Observer & Comparable<? super T>> {
List<? extends B> bList();
T observer();
}
B b = deep_stubbed.bList().iterator().next(); // returns a mock of B ; mockito remebers that A returns a List of B
Observer o = deep_stubbed.observer(); // mockito can find that T super type is Observer
Comparable<? super T> c = deep_stubbed.observer(); // or that T implements Comparable
Mockito 盡最大努力獲取編譯器嵌入的類型信息,但是當擦除適用時,mockito 只能返回Object
的模擬。
原文:嗯,與 Mockito 相比,泛型更像是一個問題。 對於泛型,你應該閱讀Angelika Langer寫的關於它們的內容。 對於當前主題,即通配符,請閱讀本節。
但簡而言之,您可以使用 Mockito 的其他語法來幫助您解決當前情況:
doReturn(interfaces).when(classAMock).getMyInterfaces();
或者使用 BDD 別名:
willReturn(interfaces).given(classAMock).getMyInterfaces();
不過,您可以編寫更通用的包裝器。 這將有助於未來的開發人員使用相同的 3rd 方 API。
附帶說明:您不應該模擬您不擁有的類型,它會導致許多錯誤和問題。 相反,您應該有一些包裝器。 例如,DAO 和存儲庫代表了這樣的想法,人們將模擬 DAO 或存儲庫接口,而不是 JDBC/JPA/hibernate 的東西。 有很多關於這個的博客文章:
另一種解決方案(雖然不太可讀)是限定when
綁定通配符的靜態方法調用:
Mockito.<List<? extends MyInterface>>when(classAMock.getMyInterfaces()).thenReturn(interfaces);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.