モック・スタブ・フェイクの使い分け(テスト効率化の実務テクニック)
クリーンアーキテクチャ+早期リターン+例外処理を活かした設計では、テスト戦略を効率化するために モック(Mock)、スタブ(Stub)、フェイク(Fake) を使い分けることが重要です。
それぞれの違い
| 種類 | 特徴 | 使いどころ | 例 |
|---|---|---|---|
| モック (Mock) | 振る舞いを定義して、呼び出しを検証できる | メソッド呼び出しや引数を確認したいとき | 「DB.save() が呼ばれたか」を確認 |
| スタブ (Stub) | 固定の戻り値を返すだけ | 外部依存を簡単に置き換えたいとき | 「APIから必ずユーザーを返す」 |
| フェイク (Fake) | 簡易的な実装を持つ | 本物に近い挙動を再現したいとき | メモリ上で動く簡易DB |
実務的サンプル
1. モックの例(呼び出し検証)
@Test
public void testRegisterUserCallsSave() {
Database mockDb = Mockito.mock(Database.class);
UserService service = new UserService(mockDb);
service.registerUser("Alice", "alice@example.com");
Mockito.verify(mockDb).save("Alice", "alice@example.com");
}
Java👉 「DB.save() が呼ばれたか」を確認するテスト。
2. スタブの例(固定値返却)
@Test
public void testGetUserProfileReturnsStubData() {
ExternalApi stubApi = Mockito.mock(ExternalApi.class);
Mockito.when(stubApi.fetchProfile("123"))
.thenReturn(new UserProfile("123", "Alice", "alice@example.com"));
UserService service = new UserService(stubApi);
UserProfile profile = service.fetchProfile("123");
assertEquals("Alice", profile.getName());
}
Java👉 「APIから必ずこのユーザーを返す」と定義してテスト。
3. フェイクの例(簡易実装)
public class FakeDatabase implements Database {
private Map<String, String> storage = new HashMap<>();
@Override
public void save(String name, String email) {
storage.put(name, email);
}
@Override
public String find(String name) {
return storage.get(name);
}
}
Java👉 実際のDBの代わりに「メモリ上で動く簡易DB」を使う。
統合テストや開発環境で便利。
まとめ
- モック: 呼び出し検証に使う(「ちゃんと呼ばれた?」を確認)。
- スタブ: 固定値返却に使う(「必ずこの結果を返す」)。
- フェイク: 簡易実装で本物に近い挙動を再現。
✅ これらを適切に使い分けることで、テスト効率が大幅に向上し、クリーンアーキテクチャの強みを最大限活かせます。
