2017-02-20 16 views
4

の一覧を注入:私はそれがMockitoを使用するためのテストを作成したいと思いますMockito - 私は次のコードを持っているモック

@Component 
public class Wrapper 
{ 
    @Resource 
    private List<Strategy> strategies; 

    public String getName(String id) 
    { 
    // the revelant part of this statement is that I would like to iterate over "strategies" 
     return strategies.stream() 
      .filter(strategy -> strategy.isApplicable(id)) 
      .findFirst().get().getAmount(id); 
    } 
} 

@Component 
public class StrategyA implements Strategy{...} 

@Component 
public class StrategyB implements Strategy{...} 

を。次のように 私がテストを書いた:

@InjectMocks 
private Wrapper testedObject = new Wrapper(); 

// I was hoping that this list will contain both strategies: strategyA and strategyB 
@Mock 
private List<Strategy> strategies; 

@Mock 
StrategyA strategyA; 

@Mock 
StrategyB strategyB; 

@Test 
public void shouldReturnNameForGivenId() 
{ // irrevelant code... 
    //when 
    testedObject.getName(ID); 
} 

私はライン上でNullPointerExceptionが取得しています:

filter(strategy -> strategy.isApplicable(id)) 

、「戦略」リストが初期化されていると述べているが、空です。 MohitoはSpringと同じように動作しますか?インターフェース "戦略"を実装しているすべてのインスタンスを自動的にリストに追加しますか?

Btw私はWrapperクラスにセッターを持っていません。できるだけその方法で残したいと思います。

答えて

1

Mockitoは、あなたがリスト戦略に気にいらを配置することを知ることができません。

あなたがこの

@InjectMocks 
private Wrapper testedObject = new Wrapper(); 

private List<Strategy> mockedStrategies; 

@Mock 
StrategyA strategyA; 

@Mock 
StrategyB strategyB; 

@Before 
public void setup() throws Exception { 
    mockedStrategies = Arrays.asList(strategyA, strategyB); 
    wrapper.setStrategies(mockedStrategies); 
} 
+0

トーマスは、春には何らかの形で知っているに明示的に「戦略」のリストを設定する必要はありませんした溶液を得るために期待していたので、Mockitoが続くことができれば、私は思っていました同じ考え。それ以外に、私はWrapperクラスに "setStrategies"セッターを追加したくありません。 – fascynacja

+0

Springは、(アプリケーションコンテキスト)を伝えるか、規約(例:Types)を使用するかのどちらかを知っています。しかし、私はSpringがGeneric Listを配線することはできないと確信しています。コンパイラは、タイプ消去フェーズのためバイトコードに書き込まないため、実行時にタイプ情報も使用できません。 だから、私は/プログラミングを教えずにモックを含む模擬リストを作成することはできないと思います。 –

+0

springはstrategyAとstrategyB beanを注入して "Wrapper"クラスをワイヤリングできます。アプリケーションのコンテキストは注釈に基づいてのみ構築されるので、私はMockitoも同じことをやり遂げることを望んでいました。 – fascynacja

2

コレクションを模倣しないでください。

必要なモックを作成し、リストに入れて:

private List<Strategy> strategies; // not mocked! 

@Mock 
StrategyA strategyA; 

@Mock 
StrategyB strategyB; 

@Before 
public void setup(){ 
    strategies= Arrays.asList(strategyA,strategyB); 
    testedObject.strategies= strategies; 
} 

@Test 
public void shouldReturnNameForGivenId() 
{ // irrevelant code... 
    //when 
    testedObject.getName(ID); 
} 
+0

ティモシーは、私が..「testedObject」 – fascynacja

0

ような何かを行う理由だけtoStream()にお電話をモックではない再考すべき?私に

@InjectMocks 
private Wrapper testedObject = new Wrapper(); 

private List<Strategy> mockedStrategies; 

@Mock 
StrategyA strategyA; 

@Mock 
StrategyB strategyB; 

@Before 
public void setup() { 
    when(strategies.stream()).thenReturn(Stream.of(strategyA, strategyB)); 
} 

これははるかにエレガントな、それはあなたのコードにテストにのみ関連し、ヘルパーメソッドを追加する必要はありませんようです。

2

@Mockの代わりに@Spyで注釈を付ける。 Mockitoはインターフェース上でスパイできないので、具体的な実装(ArrayListなど)を使用します。 テストセットアップ中に、リストスパイにモックを追加します。 このようにして、テスト目的だけを変更する必要はありません。

@InjectMocks 
private Wrapper testedObject = new Wrapper(); 

@Spy 
private ArrayList<Strategy> mockedStrategies; 

@Mock 
private StrategyA strategyA; 

@Mock 
private StrategyB strategyB; 

@Before 
public void setup() throws Exception { 
    mockedStrategies.add(strategyA); 
    mockedStrategies.add(strategyB); 
} 
+0

ありがとうございました、具体的なインプラントの説明は、私がまだ見逃していたパズルの一部です。 私はリアルメソッドの答えで@モックを試しましたが、その後は追加されません! –

関連する問題