Mockito — その概要、主要概念、動作原理

著者: IT Sectr 公開日: 2026-04-08 読了時間: 8 分

Mockitoは、JavaおよびKotlinのユニットテストでモックオブジェクトを作成するためのオープンソースフレームワークであり、テスト対象コードを外部依存関係から分離することができます。これにより、開発者は実際のリポジトリ、APIクライアント、データベースを、事前定義された動作を持つ制御可能なスタブに置き換えます。Mockito.orgによると、このライブラリはユニットテストを使用するJavaプロジェクトの60%以上で使用されています。

重要なポイント

  • Mockito — テストで実際の依存関係を置き換えるモックオブジェクトを作成するライブラリ。
  • Mock — 実際のコンポーネントの動作をシミュレートするスタブオブジェクト。
  • Stubbing — モックメソッド呼び出し時の戻り値の設定。
  • Verify — メソッドが特定の引数で呼び出されたことを確認。
  • @InjectMocks — テスト対象オブジェクトへのモック依存関係の自動注入。

Mockitoとは?

Mockitoは、Java、Kotlin、その他のJVM言語向けのユニットテストでモックオブジェクト(スタブ)を作成するためのオープンソースライブラリです。テストの実行を担当するJUnitとは異なり、Mockitoは分離の問題を解決します — テスト対象クラスの実際の依存関係を予測可能なオブジェクトに置き換えます。

モックなしでデータベースや外部APIにアクセスするメソッドをテストするには、実際の環境のセットアップ — データベースのデプロイ、サーバーの起動 — が必要です。Mockitoはこれらの依存関係を固定の動作を持つオブジェクトに置き換えます。repository.findById(1)メソッドは、データベースにアクセスせずに常に指定されたUserオブジェクトを返します。

MockitoのアーキテクチャはProxyパターン(インターフェースとクラス向け)に基づいています。ライブラリは指定された型のサブクラスまたはプロキシを生成し、すべてのメソッド呼び出しをインターセプトして、デフォルト値またはwhen().thenReturn()で設定された値を返します。

Mockitoの仕組み

Mockitoの動作原理は、モックの作成、動作の設定(スタビング)、呼び出しの検証(ベリフィケーション)の3つの基本操作に基づいています。各操作はorg.mockito.Mockitoクラスの静的メソッドを使用します — Maven Centralの統計によると、Javaエコシステムで最もダウンロードされているクラスです。すべてのモックメソッド呼び出しはメモリに記録され、後でverifyを使用して検証できます。

Mockitoを使ったテストの3つのステップ

Mockitoを使った典型的なテストは3つのフェーズで構成されます: Arrange — when().thenReturn()を使用したモックの作成とスタブの設定、Act — テスト対象メソッドの呼び出し、Assert — assertEqualsとverify(mock)を使用した結果の確認。このアプローチはAAA(Arrange-Act-Assert)と呼ばれます。

リポジトリモックを使った基本例

Mockitoがユーザーリポジトリを置き換える簡単なテストを見てみましょう。when().thenReturn()メソッドは、findById呼び出しが事前に準備されたUserオブジェクトを返すようにモックを設定します。

java
// リポジトリモックを作成
UserRepository mockRepo = mock(UserRepository.class);

// 動作を設定: findById(1)がユーザーを返す
when(mockRepo.findById(1)).thenReturn(new User("Alice"));

// メソッドが実際に呼び出されたことを確認
User result = mockRepo.findById(1);
assertEquals("Alice", result.getName());
verify(mockRepo).findById(1);

モックオブジェクトの作成

Mockitoはモックを作成する2つの方法を提供します: 静的メソッドmock(Class)と、MockitoAnnotations.openMocks()を使用した初期化を伴う@Mockアノテーションです。最初の方法は1〜2個のモックに適しており、2番目の方法は依存関係が多い場合に便利です — アノテーションによってボイラープレートコードが削減されます。

静的メソッドmock()を使用

mock()メソッドはクラスを受け取り、when().thenReturn()で設定可能なスタブオブジェクトを返します。設定されていないすべてのメソッドはデフォルト値(数値は0、ブーリアンはfalse、オブジェクトはnull)を返します。

java
ApiClient apiClient = mock(ApiClient.class);
Database database = mock(Database.class);

JUnit 5での@Mockアノテーションの使用

@Mockアノテーションと@ExtendWith(MockitoExtension.class)を組み合わせると、テストクラスのすべてのフィールドに対してモックが自動的に作成されます。MockitoExtensionは各テストの前の初期化を担当します。

java
@ExtendWith(MockitoExtension.class)
class UserServiceTest {

    @Mock
    private UserRepository userRepository;

    @InjectMocks
    private UserService userService;

    @Test
    void getUserShouldReturnUserFromRepo() {
        when(userRepository.findById(1)).thenReturn(new User("Alice"));
        User result = userService.getUser(1);
        assertEquals("Alice", result.getName());
    }
}

Stubbing: モックの動作設定

Stubbing(スタビング)とは、特定の引数で呼び出されたときにモックメソッドが何を返すべきかを定義するプロセスです。基本構文: when(mock.method(args)).thenReturn(value)。さまざまなシナリオに対応するため、Mockitoは複数のthenメソッドのバリエーションを提供しています。

メソッド目的
thenReturn(value)常に指定された値を返す
thenThrow(exception)呼び出し時に例外をスローする
thenAnswer(answer)戻り値を動的に計算する
thenCallRealMethod()実際のメソッドを呼び出す(部分モック)

thenAnswerによる動的応答

戻り値が呼び出し引数に依存する場合は、ラムダ式とともにthenAnswerを使用します。これは実際のデータを使った作業をシミュレートするのに便利です — 例えば、渡されたオブジェクトに基づいてIDを生成する場合などです。

java
when(repository.save(any())).thenAnswer(invocation -> {
    User user = invocation.getArgument(0);
    user.setId(42);
    return user;
});

Verify: モックとの相互作用の確認

Verifyは、より古いモックオブジェクトライブラリ(EasyMock、jMock)にはないMockitoのユニークな機能です。

Verifyは、戻り値だけでなく副作用 — 結果を返さないメソッド(voidメソッド)の呼び出し — もチェックするため、テストの信頼性を高めます。verify(mock).methodName(args)メソッドは、特定のモックメソッドが指定された引数で呼び出されたかどうかを確認します。これにより、結果だけでなくプロセス — 依存関係へのアクセスの事実 — もテストできます。

呼び出し回数の確認

デフォルトでは、verifyはメソッドが正確に1回呼び出されたことを確認します。異なる回数が必要な場合は、times(n)atLeast(n)never()、およびMockitoクラスのその他の修飾子を使用します。

java
// 呼び出し回数の確認
verify(repository, times(3)).save(any());
verify(repository, never()).delete(any());
verify(repository, atLeastOnce()).findById(1);

// 呼び出し順序の確認
InOrder inOrder = inOrder(repository);
inOrder.verify(repository).save(any());
inOrder.verify(repository).flush();

引数キャプチャのためのArgumentCaptor

メソッドがどのオブジェクトで呼び出されたかを正確に確認する必要がある場合は、ArgumentCaptorを使用します。これは呼び出し中に引数の値をキャプチャし、そのフィールドを個別に確認できます。ArgumentCaptorは、テスト対象コードが内部でオブジェクトを作成し、それを依存関係に渡す場合に特に便利です — そうでなければそのオブジェクトを確認できません。

java
ArgumentCaptor<User> captor = ArgumentCaptor.forClass(User.class);
verify(repository).save(captor.capture());
assertEquals("Alice", captor.getValue().getName());

@Mockと@InjectMocksアノテーション

@Mock@InjectMocksは、ボイラープレートコードを大幅に削減する2つの主要なMockitoアノテーションです。@Mockはフィールドのモックを作成し、@InjectMocksはテストクラスからすべてのモックを、コンストラクター、セッター、またはフィールドを介してテスト対象オブジェクトに注入します。

@InjectMocksのメカニズムは、次の順序で依存関係の注入を試みます: 最も多くの引数を持つコンストラクター、型によるセッター、プライベートフィールド。これらのいずれも機能しない場合、オブジェクトはnullの依存関係のままになり、テストはNullPointerExceptionで失敗します。

@InjectMocks使用のルール

重要なのは:@InjectMocksはフィールドの型を分析しません — 型互換性のある任意のモックを代入します。クラスに同じ型のフィールドが2つある場合、Mockitoは誤ったモックを注入する可能性があります。そのような場合は、モックパラメーターを持つ明示的なコンストラクターを使用することをお勧めします。

AndroidプロジェクトでのMockito

Android開発では、MockitoはJUnitと一緒にViewModel、Repository、UseCaseのテストに使用されます。これらのクラスはAndroidコンテキストなしでJVM上で実行されるため、Mockitoはそれらの依存関係 — Room DAO、Retrofit API、SharedPreferences — を予測可能な動作のスタブに置き換えます。

MockitoのGradle設定

AndroidプロジェクトにMockitoを追加するには、mockito-coreまたはmockito-inlineの依存関係を追加するだけです(後者はfinalクラスと静的メソッドのモック化をサポートしています)。バージョン5.12.0(2024年)にはJava 21のサポートと改善されたJUnit 5統合が含まれています。

kotlin
// build.gradle.kts (module)
dependencies {
    testImplementation("org.mockito:mockito-core:5.12.0")
    testImplementation("org.mockito:mockito-junit-jupiter:5.12.0")
}

MockitoとPowerMock: 時代遅れの手法

以前は、静的メソッドとコンストラクターのモック化にはPowerMock — バイトコードインストゥルメンテーションを通じて動作する拡張機能 — が必要でした。Mockito 5.x以降のmockito-inlineでは、この機能が直接組み込まれています: mockStatic(ClassName.class)を使用すると、追加のライブラリーなしで静的メソッドをモック化できます。

Mockitoを使ったViewModelのテスト

典型的なシナリオ: ViewModelがリポジトリメソッドを呼び出し、結果をUI状態に変換します。Mockitoがリポジトリを置き換え、テストはViewModelが成功応答とエラーの両方を正しく処理することを確認します。Clean Architectureを使用する場合、各レイヤー(DataSource、Repository、UseCase)に対してモックが作成されます — これにより各レイヤーを個別にテストできます。

  • 成功ケース — when(repo.getData()).thenReturn(Result.success(data)) → state = Success(data) を確認。
  • エラーケース — when(repo.getData()).thenReturn(Result.error(exception)) → state = Error(message) を確認。
  • ローディング状態 — ViewModelがリポジトリ呼び出し前にisLoading = trueを設定したことをverifyで確認。

よくある質問

MockitoとMockKの違いは何ですか?

Mockitoはプロキシとリフレクションを使用するJavaおよびKotlin向けのライブラリです。MockKはコルーチン、拡張関数、finalクラスを追加設定なしでサポートするKotlinファーストのライブラリです。

Mockitoでfinalクラスのモックを作成するには?

Mockito 2.1以降、finalクラスのモック化はオプトインでサポートされています。バージョン5.x(mockito-inline)では、これはデフォルトで有効です。mockito-inlineの依存関係を追加し、標準のmock()メソッドを使用するだけです。

MockitoのSpyとは何ですか?

Spyは部分的なモックで、デフォルトでは実際のメソッドを呼び出しますが、when().thenReturn()を使用していくつかのメソッドをオーバーライドできます。Spyは、クラス全体を書き換えられないレガシーコードのテストに便利です。

thenReturnとthenAnswerの違いは何ですか?

thenReturnは引数に関係なく常に同じ値を返します。thenAnswerは呼び出し — 引数、モック自体、状態 — に基づいて戻り値を計算します。動的な応答には常にthenAnswerを使用してください。

モックを使ったテストでverifyが重要な理由は?

Verifyは結果だけでなく、プロセス — 依存関係へのアクセスの事実 — もチェックします。これはデータを保存したり通知を送信したりする必要があるサービスにとって重要です。verifyがないと、テストはメソッドがsave()やsend()を呼び出さなかったことを検出できません。

まとめ

  • Mockito — モックオブジェクトを作成するためのライブラリ、JavaとKotlinでのモック化のデファクトスタンダード。
  • モックはmock(Class)またはMockitoExtensionを使用した@Mockアノテーションで作成されます。
  • Stubbing(when().thenReturn())でモックメソッドの動作を定義します。
  • Verifyは指定された引数でのモックメソッド呼び出しの有無と回数を確認します。
  • @InjectMocksはテスト対象オブジェクトにモックを自動注入します。
  • Android統合 — MockitoはViewModel、Repository、UseCaseのテストに使用されます。
  • ArgumentCaptorは詳細なオブジェクトフィールド確認のために呼び出し引数をキャプチャします。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください