2016-12-07 13 views
1

私はジェネリックスとワイルドカードをJava 8で頭に浮かべています。しかし、なぜこのリポジトリメソッドをモックできないのか理解できません。 コードはとてもシンプルなので、再現しやすいはずです。一般的なワイルドカードからの返信を模擬する方法

私は ""

The method thenReturn(Stream<capture#1-of ? extends Something>) in the type 
OngoingStubbing<Stream<capture#1-of ? extends Something>> is not applicable 
for the arguments (Stream<capture#3-of ? extends Something>) 

テストの "thenReturn" の部分で、このコンパイルエラーを持っている:

@Test 
public void ItShourReturnStreamFromRepository() { 
    List<Something> list = new ArrayList<Something>(); 
    list.add(new Something()); 
    Stream<? extends Something> stream = list.stream(); 
    when(someRepository.getStream()).thenReturn(stream);  
} 

クラス:

public class Something {} 

リポジトリ:

public interface SomeRepository{ 
    Stream<? extends Something> getStream(); 
} 

誰か助けてもらえますか? ありがとう!

+1

[公式チュートリアル](http://docs.oracle.com/javase/tutorial/java/generics/wildcardGuidelines.html)の推奨事項に従ってください。*戻り値の型としてワイルドカードを使用することは避けてください。* – Holger

+2

どのようにタイプをインタフェースに追加するのですか?インターフェースSomeRepository {Stream getStream(); } ' –

答えて

5

これはワイルドカードタイプの一般的な問題です。単純化され、Mockitoに依存しない例でそれを実証するために:

Enum<?> e = Thread.State.BLOCKED; 

// produces "incompatible types: Enum<CAP#1> cannot be converted to Enum<CAP#2>" 
Arrays.asList(e).set(0, e); 

// works since Java 8 
List<Enum<?>> list=Arrays.asList(e); 
list.add(e); 

// works even in older versions 
Arrays.<Enum<?>>asList(e).set(0, e); 

これはあなたにもMockitoのAPIで動作するはず可能な解決策を指します。しかし、SomeRepositoryのようなAPIを設計するためにあなたは、一般的な“Guidelines for Wildcard Use”を、次の必要があります。

それがワイルドカードに対処するためのコードを使用して、プログラマを強制するので避けるべきである戻り値の型としてワイルドカードを使用しました。

ストリームの要素タイプの? extendsは、何のメリットもない複雑化をもたらします。より具体的なタイプのソースからでも、いつでもStream<Something>を作成できます。

SubTypeOfSomething subTyped = … 

// from specific values 
Stream<Something> s1 = Stream.of(subTyped); 

// from existing collection 
Set<SubTypeOfSomething> set = Collections.singleton(subTyped); 
// note: this creates the stream directly from the source set 
Stream<Something> s2 = Collections.<Something>unmodifiableSet(set).stream(); 

// if you really unavoidably have a more specifically typed Stream 
Stream<SubTypeOfSomething> s3 = set.stream(); 
Stream<Something> s4 = s3.map(Function.identity()); 

Stream<? extends Something>Stream<Something>があまりにも提供していないものを提供していません。インタフェースが代わりに入力した場合、それは違うものになるでしょう

RC’s suggestionを次のように:

interface SomeRepository<T extends Something> { 
    Stream<T> getStream(); 
} 

その後、あなたはもう、ワイルドカードを持っていない、より具体的に型指定されたストリームは、利益を提供するかもしれません。

関連する問題