簡體   English   中英

使用 mockito 模擬返回帶有通配符的泛型的方法

[英]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.

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