🕒 学習時間
10:30~11:30
🧑💻 実施した学習内容
1. 疑問点
Mockitoのany()とは
2. 技術の概要
◾️何をするものか
Mockitoのany()は「引数マッチャー(Argument Matcher)」の一種で、
「どんな値が渡されてもOK」とするための仕組み。
◾️背景・目的(なぜ必要か)
テストでは「値そのもの」ではなく「振る舞い(メソッドが呼ばれたか)」を検証したいケースが多い。
→ 毎回具体的な値を指定するとテストが冗長・脆くなるため、
「値は何でもいい」という抽象化が必要になる。
3. 内容
Mockitoでは通常、引数はequalsで比較される。
when(service.get("A")).thenReturn("OK");
→ "A"と完全一致しないとマッチしない
しかし、any()を使うと:
when(service.get(any())).thenReturn("OK");
→ 引数が何であってもOK
つまり、
「値の一致チェックをスキップする仕組み」
ポイント:
- any()は「任意の値(null含む)」にマッチ :contentReference[oaicite:0]{index=0}
- 型付き版もある(anyString, anyIntなど) :contentReference[oaicite:1]{index=1}
4. 用語定義
- モック(Mock):
テスト用の偽物オブジェクト - スタブ(Stub):
「この入力ならこの出力を返す」と決める設定 - 検証(verify):
メソッドが呼ばれたかチェック - 引数マッチャー:
引数の条件を柔軟に指定する仕組み
5. 解決する課題・メリット
- テストコードの簡略化
- 動的な値(ID・日時など)に対応できる
- 本質的な振る舞いに集中できる
例:
verify(repo).save(any());
→ 「saveが呼ばれたか」だけを検証できる
6. 使用する注意事項・デメリット
① matcherは統一が必要
//NG
when(service.get(any(), "A"))
//OK
when(service.get(any(), eq("A")))
→ matcherと通常値は混在不可
② any()はnullを返すことがある
→ プリミティブ型でNPE注意 :contentReference[oaicite:2]{index=2}
③ 値の検証が弱くなる
→ 重要な値はeq()を使うべき
7. 類似技術との比較
| 技術 | 意味 | 用途 |
|---|---|---|
| any() | 何でもOK | 値を気にしない |
| eq(x) | xと一致 | 特定値を検証 |
| argThat() | 条件指定 | 複雑な条件 |
| isNull() | nullのみ | nullチェック |
8. インストール・環境構築
Gradle:
implementation 'org.mockito:mockito-core:5.x.x'
JUnit5:
testImplementation 'org.junit.jupiter:junit-jupiter:5.x.x'
9. 基本的な使い方・実装(サンプルコード)
import static org.mockito.Mockito.*;
import static org.mockito.ArgumentMatchers.*;
class UserService {
String getUser(String id) {
return "real";
}
}
public class TestExample {
public static void main(String[] args) {
// モック作成
UserService mock = mock(UserService.class);
// any()で「どんな引数でもOK」にする
when(mock.getUser(any())).thenReturn("mocked");
// 実行
System.out.println(mock.getUser("123")); // mocked
System.out.println(mock.getUser("999")); // mocked
}
}
◾️解説
- any() → 引数チェックをスキップ
- 同じ戻り値を返す
- テストの柔軟性が上がる
10. デザインパターン(サンプルコード)
Strategy的発想(比較ロジックの切り替え)
// マッチング戦略インターフェース
interface MatcherStrategy {
boolean match(String input);
}
// 任意一致(any的)
class AnyMatcher implements MatcherStrategy {
public boolean match(String input) {
return true; // 常にtrue
}
}
// 特定一致(eq的)
class ExactMatcher implements MatcherStrategy {
private String expected;
public ExactMatcher(String expected) {
this.expected = expected;
}
public boolean match(String input) {
return expected.equals(input);
}
}
◾️解説
- any()は「常にtrueの戦略」
- eq()は「一致戦略」
→ Mockito内部はこういう抽象化で動く
11. アンチパターン(サンプルコード)
// 悪い例:全部any()
when(service.create(any(), any(), any())).thenReturn(true);
◾️問題
- 何をテストしているかわからない
- バグを見逃す
改善:
when(service.create(eq("user"), any(), any())).thenReturn(true);
→ 重要な値だけ固定