2016-04-13 2 views
0

私は、カスタマイズされたrandomizerからの戻り値を模擬するために何百ものテストで使用されるユーティリティメソッドを持っています。ここに私のコードの(非常に人工的な)モデルがあります:検証として `when`を使う

interface CardRandomiser{ 
    Card getCard(Suit suit); 
} 

void mockCard(Suit suit, Face face) { 
    CardRandomiser rand = mock(CardRandomiser.class); 
    when(rand.getCard(suit)).thenReturn(new Card(suit, face)); 
    Game.setCardRandomiser(rand); 
} 

これは、その後に使用することができます。

mockCard(Suit.CLUBS, Face.QUEEN); 
Card card = pickACardAnyCard(); 
assertThat(card.getFace(), is(Face.QUEEN)); 

しかし、これはピックアップするいくつかのバグが少し難しいことができます。テスト中のメソッドが間違ってSuit.HEARTSを要求すると、モックはnullを返し、アサーションは正しく失敗します。しかし、エラーメッセージを通して模擬に渡されたものを伝えることは不可能です。

明らかに私はこれをverifyで処理できました。私はmockCardの機能からモックを戻して、別の値が正しい値で呼び出されたことを別に確認することができます。しかし、それは本当にテストされているものと実際には関係のないテストアサーションを混乱させる。このメソッドが呼び出されるたびに、私は期待される引数の値を指定しています。私はそのアサーションを1か所に置くことをお勧めします。これはすべて、の前にが発生し、テスト中のメソッドが呼び出されることに注意してください。

理想的には、予期しない値で呼び出された場合、whenステートメントに例外がスローされるようにしたいと考えています。以下のような何か:

when(rand.getCard(suit)).thenReturn(new Card(suit, face)); 
when(rand.getCard(intThat(not(is(suit))))).thenThrow(new IllegalArgumentException()); 

これは動作しgetCardが優れていると呼ばれるテストを停止します。しかし、それでも私は間違った議論が何であるかを私に見せてくれません。

また、ArgumentCaptorを使用して試してみました。キャプチャした値を確認しました。しかし、whenステートメントではなく、verifyステートメントであることは明らかです。

これを行うための標準的なMockito方法がありますか、またはverify文でテストを乱雑にする必要がありますか?

答えて

2

thenAnswerを使用して、mockitoの回答を設定することができます。

private CardRandomiser mockCard(final Suit suit, final Face face) { 
    CardRandomiser rand = mock(CardRandomiser.class); 

    when(rand.getCard(any(Suit.class))).thenAnswer(new Answer<Card>() { 
     @Override 
     public Card answer(InvocationOnMock invocation) throws Throwable { 
      if(!suit.equals(invocation.getArguments()[0])) { 
       throw new IllegalArgumentException(
         String.format("Value %s passed, but mocked for %s", invocation.getArguments()[0], suit)); 
      } 
      return new Card(suit, face); 
     } 
    }); 

    return rand; 
} 
+0

これは完璧です。ありがとう。 – sprinter

関連する問題