2011-12-23 4 views
0


とジェネリック戻り値の型を持つメソッドは、私の問題です:モックmockitoここ

public interface Containter extends ModelElement{ 
    List<? extends ModelElement> getChildren(); 
} 

ありContainterを実装するいくつかのクラスがあり、私はそれらをモックとしたい:

public class MockMama { 
    public static <T extends Containter, Y extends ModelElement> T bornContainer(Class<T> clazz, Y ... children) { 
      T container = mock(clazz); 
      when(container.getChildren()).thenReturn(Arrays.asList(children)); 
      return container; 
    } 
} 

しかしこのdoesnの仕事はありません。 Eclipseでは "OngoingStubbing型のメソッドthenReturn(List)は引数(List)には適用されません"と表示されます。私はまた、リスト<? extends ModelElement>型のローカル宣言された変数をthenReturnに渡そうとしましたが、これはどちらも役に立ちませんでした。
助けを歓迎します:

+0

[OK]をクリックすると、 のような余分なローカル変数を導入することで修正できるようです。List list = Arrays.asList(children); when(container.getChildren())。then返す(リスト); 生のタイプの警告を出さずにこれを行う方法はありますか? – user656449

答えて

2

getChildren()が返す型が、あなたのbornContainerメソッドのvarargs引数の型と一致するという保証はありません。したがって、コンパイラはこれについて不平を言うのは正しいです。中間のローカル変数を使用すると、実際にはコンパイラのエラーが潜在的なランタイム問題になります。

「Container」は、getChildren()が返すリストの型に依存するため、実際には「Container」はジェネリッククラスである必要があります。あなたの事例を書き直してみてください。これにはコンパイルエラーや警告はありません。

public interface Containter<Z extends ModelElement> extends ModelElement{  
    List<Z> getChildren(); 
} 

public class MockMama {  
    public static <Y extends ModelElement, T extends Containter<Y>> T bornContainer(Class<T> clazz, Y ... children) {    
     T container = mock(clazz);    
     when(container.getChildren()).thenReturn(Arrays.asList(children));    
     return container;  
    } 
} 

これが役に立ちます。

+0

ありがとうございます。しかし、コンテナは実際には一般的ではありません。あらゆるタイプのModelElementsを返すことができるはずです。また、私は申し訳ありませんが、質問にはタイプミスがあります.Z2ModelElementsはありません。すべてのemelentsはModelElementsだけです。したがって、コンテナのgetChildrenとメソッドgenericは両方ともY extends ModelElementですが、なぜ追加の保証が必要ですか? – user656449

+0

'getChildren'によって返される' Y'は 'bornContainer'に渡される' Y'と必ずしも一致しないので、コンパイラはあなたをあなた自身から守ろうとしています。しかし、これらのメソッドが 'ModelElement'のどんな型にも対応できるならば、' Y'を完全に削除することができます。つまり、 'getChildren'の戻り値の型は' List 'となります。 'bornContainer'へのパラメータは単に' ModelElement ... 'となります。 –

+0

Ok。私は理解したと思う。ありがとうございました。 – user656449

0

通常、テストでは未チェックまたは生のタイプの警告を無視できます。だから、普通は@SupressWarning("unchecked")のようなコンパイラ指令でテストに注釈を付けるのが安全です。

+0

まあ、はい、それは抑制することができますが、元のコードがコンパイルされない理由を理解できません。そして、これは私を緊張させる:)私はこれがなんらかの種類のものだと感じている "もしyの場合を除いて、yを除いてxを行うことができる。その場合、もしそうなら..." Ken Arnoldはhttp:// weblogsについて語る.java.net/blog/arnold/archive/2005/06/generics_consid.html – user656449

関連する問題