Mockitoでモックを使ったテストを書いていると、「引数が10より大きい場合だけ動作させたい」「ある条件を除外したい」といった柔軟な条件指定をしたくなる場面がよくあります。
しかし、Mockitoが標準で提供する ArgumentMatchers
では、こうした複雑な条件を表現しきれないことも少なくありません。
そんなときに役立つのが、Mockitoの補助的なマッチャークラス AdditionalMatchers
です。
この記事では、AdditionalMatchers
の使い方や代表的なマッチャー、使用上の注意点までを実例とともに丁寧に解説します。
AdditionalMatchersとは?
AdditionalMatchers
は、Mockitoが標準で提供するArgumentMatchers
では実現できない、より高度なマッチング処理を可能にするユーティリティクラスです。
インポート方法
import static org.mockito.AdditionalMatchers.*;
代表的なユースケース
具体的には、以下のような条件指定が可能になります。
- 数値の大小比較(例:10より大きい)
- 複数条件の組み合わせ(AND / OR / NOT)
- 浮動小数点の誤差許容比較
- 正規表現マッチング
- 配列の内容比較
こうした機能を使うことで、テストコードの柔軟性と表現力を大幅に高めることができます。
各メソッドの解説
ここからは、AdditionalMatchers
が提供するマッチャーメソッドを種類ごとに紹介します。実際の使用例を交えながら、目的に応じた使い分けができるように整理しました。
gt(T value)
/ lt(T value)
/ geq(T value)
/ leq(T value)
指定値との大小比較を行うマッチャーです。
メソッド | 意味 | 使用例 |
---|---|---|
gt(value) | valueより大きい | gt(10) → 11, 20 などにマッチ |
lt(value) | valueより小さい | lt(5) → 1, -1 などにマッチ |
geq(value) | value以上 | geq(10) → 10, 20 などにマッチ |
leq(value) | value以下 | leq(3) → 3, 2 などにマッチ |
when(mock.add(gt(10))).thenReturn(true);
→ 引数が 10 より大きい範囲にマッチ
and(T first, T second)
2つの条件を同時に満たす場合にマッチします。
when(mock.add(and(gt(10), lt(20)))).thenReturn(true);
→ 引数が 10 より大きく 20 より小さいの範囲にマッチ
or(T first, T second)
いずれか一方の条件を満たせばマッチします。
when(mock.add(or(eq(1), eq(100)))).thenReturn(true);
→ 引数が 1 または 100 にマッチ
not(T matcher)
指定したマッチャーに一致しない引数にマッチします。
when(mock.add(not(eq(0)))).thenReturn(true);
→ 引数が 0 以外のすべてにマッチ
cmpEq(Comparable<T> value)
compareTo()
で比較して、等しいと判定される値にマッチします。equals()
ではなく、Comparable
の自然順序に基づく比較が行われます。
when(mock.search(cmpEq(BigDecimal.valueOf(10.0)))).thenReturn("found");
→ 引数が new BigDecimal("10.00")
でもマッチ(compareTo
的に等価なので)
find(String regex)
正規表現に一致する値にマッチします。Stringの引数のみ利用可能です。
when(mock.search(find("^10"))).thenReturn("found");
→ 引数が “10” から始まる文字列にマッチ
eq(double value, double delta)
/ eq(float value, float delta)
浮動小数点数同士を、指定した誤差範囲(デルタ)内で等しいとみなすマッチャーです。
when(mock.calculate(eq(3.14, 0.01))).thenReturn("pi");
→ 引数が 3.13〜3.15 の範囲ならマッチ
double の比較は誤差の影響を受けるため、通常の eq(3.14) ではうまく動作しないことがあります。
aryEq(T[] array)
配列の内容が等しいかを比較します(equals
ではなくArrays.equals
相当の比較)。
when(mock.setData(aryEq(new int[]{1, 2, 3}))).thenReturn(true);
→ 引数の配列が [1, 2, 3]
と等しいとマッチ
使用上の注意点
AdditionalMatchers
を使う際には、いくつか注意すべきポイントがあります。特に、Mockitoにおける引数マッチャーの扱いのルールには気をつけましょう。
すべての引数をマッチャーで統一すること
Mockitoでは引数が複数存在する場合、一部の引数にだけマッチャーを使うとエラーになります。
// ❌ NG:マッチャーとリテラル値を混在させると例外が発生
verify(mock).add(gt(3), 5); // これは例外発生
// ✅ OK:すべての引数にマッチャーを使用
verify(mock).add(gt(3), gt(5));
これはMockitoの仕様であり、引数が混在していると内部で一致判定が正しく行えなくなるためです。
可読性と意図の明確化も重要
マッチャーを組み合わせると複雑な条件を表現できますが、その分 可読性が下がりやすくなります。
// 読みにくい例
when(service.process(and(gt(10), not(eq(42))))).thenReturn(true);
このような場合は、条件を事前にコメントで説明したり、カスタムマッチャーに切り出すとテストの意図が明確になります。
マッチャーはMockito専用の文脈でのみ有効
AdditionalMatchers
(および ArgumentMatchers
)は、when()
や verify()
などMockitoの文脈内でのみ利用可能です。
通常のコードロジックやassert
文などでは使用できない点にも注意してください。
まとめ:柔軟な条件指定でMockitoの真価を引き出す
AdditionalMatchers
は、Mockitoの柔軟な引数マッチングをさらに拡張してくれる強力なユーティリティです。
「数値が特定の範囲内にある」「ある条件を除外したい」「複数条件を組み合わせたい」といったケースでは、ArgumentMatchers
だけでは表現が難しいこともあります。そうした場面で AdditionalMatchers
を使えば、より直感的で強力なテスト記述が可能になります。
ただし、使用時にはすべての引数をマッチャーで統一する必要があるなど、いくつかの注意点もあります。可読性にも配慮しつつ、必要に応じてコメントや補助的な関数で補強するとよいでしょう。
柔軟で意図が明確なマッチャーを活用することで、テストの信頼性とメンテナンス性を大きく高めることができます。
ぜひプロジェクトの単体テストに AdditionalMatchers
を取り入れて、Mockitoの可能性を最大限に引き出してみてください。