web-dev-qa-db-ja.com

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がサードパーティから提供されていて変更できない場合、この問題を解決する他の方法はありますか?

46
user1504992

[〜#〜] edit [〜#〜]:Mockito 1.10.x以降、クラスに埋め込まれているジェネリック型がMockitoで使用されるようになりました深いスタブ用。すなわち。

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のモックを返す以外に何もできません。


Original:それは、Mockitoよりもジェネリックに関する問題です。ジェネリック医薬品については、Angelika Langerが書いたものを読む必要があります。そして現在のトピック、すなわちワイルドカードについては、これを読んでください セクション

しかし、簡単に言えば、あなたが使用できるのはあなたの現在の状況を助けるためのMockitoの他の構文です:

doReturn(interfaces).when(classAMock).getMyInterfaces();

または、BDDエイリアスを使用する場合:

willReturn(interfaces).given(classAMock).getMyInterfaces();

それにもかかわらず、より汎用的なラッパーを作成できます。これは、同じサードパーティAPIを使用する将来の開発者を支援します。


副次的な注意事項として、所有していないタイプのモックを作成しないでください。多くのエラーや問題が発生する可能性があります。代わりに、ラッパーが必要です。たとえば、DAOとリポジトリはそのような考えを表しています。1つはDAOまたはリポジトリインターフェイスをモックしますが、JDBC/JPA /休止状態のものはモックしません。それに関する多くのブログ投稿があります:

58
Brice

別の解決策(読みにくいが)は、whenの静的メソッド呼び出しを修飾して、ワイルドカードをバインドすることです。

Mockito.<List<? extends MyInterface>>when(classAMock.getMyInterfaces()).thenReturn(interfaces);
46
thSoft