Mockito ArgumentMatchers

1.概要

このチュートリアルは ArgumentMatcher _の使い方と ArgumentCaptor_ との違いを示します。

Mockitoフレームワークの紹介については、 この記事へ を参照してください。

2. Mavenの依存関係

単一の成果物を追加する必要があります。

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>2.21.0</version>
    <scope>test</scope>
</dependency>

Mockito の最新バージョンが見つかります。 Maven Central で。

3. ArgumentMatchers

モックメソッドをさまざまな方法で設定することが可能です。そのうちの1つは固定値を返すことです。

doReturn("Flower").when(flowerService).analyze("poppy");

上記の例では、 String “ Flower”は分析サービスが String “ poppy”を受信した場合にのみ返されます。

しかし、 もっと広い範囲の値や、事前に未知の値に対応する必要があるかもしれません

これらのすべてのシナリオで、 argument __ matchers でモックメソッドを設定できます。

when(flowerService.analyze(anyString())).thenReturn("Flower");

さて、 anyString 引数マッチャーのために、どんな値を分析に渡しても結果は同じになります。 ArgumentMatchers を使用すると、柔軟な検証またはスタブ作成が可能になります。

メソッドに複数の引数がある場合、** 引数の一部だけに ArgumentMatchers を使用することはできません。 Mockito では、すべての引数を matchers または正確な値で指定する必要があります。

次の例は、これに対する誤ったアプローチです。

abstract class FlowerService {
    public abstract boolean isABigFlower(String name, int petals);
}

FlowerService mock = mock(FlowerService.class);

when(mock.isABigFlower("poppy", anyInt())).thenReturn(true);

それを修正して String の名前を望みどおりに「ポピー」にするには、 eq matcher を使用します。

when(mock.isABigFlower(eq("poppy"), anyInt())).thenReturn(true);

__matcher __が使われるときに注意するべきもう2つのポイントがあります:

  • これらを戻り値として使用することはできません

スタブコール 最後に、 検証の外では matchers 引数を使用できません

スタブ**

最後のケースでは、 Mockito は見当違いの引数を検出し、 InvalidUseOfMatchersException をスローします。

悪い例は次のようになります。

String orMatcher = or(eq("poppy"), endsWith("y"));
verify(mock).analyze(orMatcher);

上記のコードを実装する方法は次のとおりです。

verify(mock).analyze(or(eq("poppy"), endsWith("y")));

Mockito は、 ArgumentMatchers で共通の論理演算(「not」、「and」、「or」)を実装するための AdditionalMatchers も提供します。これらは、プリミティブ型と非プリミティブ型の両方に一致します。

verify(mock).analyze(or(eq("poppy"), endsWith("y")));

4.カスタム引数マッチ

私たちの matcher を作成することは、与えられたシナリオに対して可能な限り最善のアプローチを選択し、最高品質のテスト** を生成するのに良いことです。

たとえば、メッセージを配信する MessageController があります。それは MessageDTO を受け取り、そこから MessageService によって配信される Message を作成します。

確認は簡単です。ManyageServiceを__any Messageで1回呼び出したことを確認します。

verify(messageService, times(1)).deliverMessage(any(Message.class));
  • Message はテスト中のメソッド内で構築されているため、 matcher として any を使用する必要があります。

このアプローチでは、 Message 内のデータを検証することはできません。これは、 MessageDTO 内のデータとは異なる場合があります。

そのため、カスタム引数マッチャーを実装します。

public class MessageMatcher implements ArgumentMatcher<Message> {

    private Message left;

   //constructors

    @Override
    public boolean matches(Message right) {
        return left.getFrom().equals(right.getFrom()) &&
          left.getTo().equals(right.getTo()) &&
          left.getText().equals(right.getText()) &&
          right.getDate() != null &&
          right.getId() != null;
    }
}
  • マッチャーを使うには、テストを修正して any argThat ** に置き換える必要があります。

verify(messageService, times(1)).deliverMessage(argThat(new MessageMatcher(message)));

これで、 Message インスタンスは MessageDTO と同じデータを持つことがわかりました。

5.カスタム引数マッチャーと ArgumentCaptor

両方のテクニック カスタム引数matchers ArgumentCaptor を使用して、特定の引数がモックに渡されるようにすることができます。

ただし、検証を完了するために引数値をアサートする必要がある場合、またはカスタム引数matcher が再利用される可能性がない場合は、 ArgumentCaptor__が適している可能性があります 。

ArgumentMatcher を介した カスタム引数matchers は、通常スタブ処理に適しています。

6.まとめ

この記事では、 Mockito ArgumentMatcher の機能、および__ArgumentCaptorとの違いについて説明しました

いつものように、例の完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/spring-mockito[over on GitHub]から入手可能です。

前の投稿:Spring Securityフィルタチェーンのカスタムフィルタ
次の投稿:Java Weekly、第253号