R e i - D r e a m
for Laravel
Guest
login

最終投稿日:2026年09月27日

ユニットテストサマリ

モックインスタンスの種類と返却制御

モックの種類により返却値を設定する方法も変わってきます。
ここを抑えるとユニットテストの理解が更に進むと思います。
● 通常モック
《書式》
Xxxxx mockHoge = mock(Xxxxx.class)
例)
SampleDto mockSampleDto = mock(SampleDto.class);
《targetにセット必要》
Field field = {targetクラス}.class.getDeclaredField("{モック対象インスタンス名}");
field.setAccessible(true);
field.set({関連付け元インスタンス}, {モックインスタンス});
例)
Field field = SampleService.class.getDeclaredField("appLogic");
field.setAccessible(true);
field.set(target, mockAppLogic);
《返却値設定方法》
doAnswer(invocation -> {
    // 色々処理を記述できます
    return {制御したい返却値};
}).when({モックインスタンス}).{対象メソッド}({引数がある場合は指定});
例)
doAnswer(invocation -> {
    List<User> list = new ArrayList<>();
    // 空のリストを返却
    return list;
}).when(mockAppLogic).selectHoge(any());
または、
doReturn(new ArrayList()).when(mockDao).findAll();
ポイント

モックインスタンスの返却値を設定する際のメソッドの引数は厳密に判定されます。
例えば同じメソッドで引数が違うコードが2行あったとすると、テスト側で設定した引数にマッチする方が対象となります。
これをアバウトに設定できるのが『any()』だったりします。([マッチャー]と言います)

『any()』の他にも以下の様なマッチャーがあります。
    any(UserDto.class), anyString(), anyList(), nonNull(), isNotNull(), isNull()
また、テスト対象がループ処理している場合の返却値設定も使用頻度が高いです。
そんな場合はカンマ区切りで以下の様に記述できます。
    when(mockDao.getName(any())).thenReturn("A", "B", "C");

● SPYモック
《書式》
Xxxxx spyTarget = new Xxxxx();
例)
private NextService target = new NextService();
private NextService spyTarget = new NextService();
《targetにセット必要》
{テストターゲット} = Mockito.spy({SPYターゲット}); 例)
target = Mockito.spy(spyTarget);
《返却値設定方法》
通常モックと同じです。
    ※『when』の引数は『target』となります
● staticモック
《書式》
MockedStatic<{モックにするクラス}> mockHoge = mockStatic({モックにするクラス}.class);
例)
MockedStatic mockDateUtil = mockStatic(DateUtil.class);
《返却値設定方法》
{モックインスタンス}.when({実際のstaticクラス}::{実際のstaticメソッド}).thenReturn({返却値});
例)
mockDateUtil.when(DateUtil::getNowToString).thenReturn("20260101");
または、
mockDateUtil.when(DateUtil::getNowToString).thenAnswer(invocation -> {
    String now = "20260101";
    return now;
});
《close()が必要》
@AfterEach
void After() {
    if (mockDateUtil != null) {
        mockDateUtil.close();
    }
}

検証用関数一覧

今までサンプルでは『assertEquals』のみを使用していましたが、実はもっと沢山あります。
assertEquals(x, y) xとyが等しい(equals() == trueである)ことを検証
assertNotEquals(x, y) xとyが等しくない(equals() == falseである)ことを検証
assertArrayEquals(x, y) 配列xとyのすべての要素が順番通りに等しい(equals() == trueである)ことを検証
assertIterableEquals(x, y) Iteratable(Listなど)なxとyのすべての要素が順番通りに等しい(equals() == trueである)ことを検証
assertNotNull(x) xがnullでないことを検証
assertNull(x) xがnullであることを検証
assertTrue(x) xがtrueであることを検証
assertFalse(x) xがfalseであることを検証
assertSame(x, y) xとyが同一オブジェクト(x == yである)ことを検証
assertNotSame(x, y) xとyが異なるオブジェクト(x != yである)ことを検証
assertInstanceOf(c, x) xが指定したクラスcのオブジェクトであることを検証
    ※ assertInstanceOf(String.class, value);
assertLinesMatch(x, y) yがxで指定したパターンのListまたはStreamであることを検証
assertThrows(e, f) 処理fが例外クラスeまたはそのサブクラスをスローすることを検証
    ※ fはラムダ式 () -> {hello.greet("hoge");}
assertThrowsExactly(e, f) 処理fが例外クラスeをスローすることを検証
    ※ fはラムダ式 () -> {hello.greet("hoge");}
assertDoesNotThrow(f) 処理fが例外クラスをスローしないことを検証
assertTimeout(t, f) 処理fが指定した時間t内に終わることを検証
    ※ 処理は最後まで実行される
assertTimeoutPreemptively(t, f) 処理fが指定した時間t内に終わることを検証
    ※ 処理はタイムアウトになった時点で終了する
○ assertThrows
ラムダ式が少しわかりにくいので、以下サンプルとなります。
assertThrows(CruiseRuntimeException.class, () -> {target.greet("hoge");});

最後に

いかがでしたか?
モックの種類により若干クセがありますが、種類自体少ないので何とかなりそうですよね。
ユニットテストは打鍵テストとは違い『テストコードを作成する』手間があるので一見面倒に思えます。
しかしそれは打鍵テストでもデータを揃えたりしますよね。
で、ビルドして画面の動作をキャプチャとして証跡に残す。
しかしユニットテストであれば圧倒的な以下のメリットがあります。
・圧倒的な再現性
・圧倒的なテスト実行速度
・正確なカバレッジ測定
・見えない異常系・境界値のテストが容易
・例外など打鍵操作では再現が極めて困難(または不可能)な異常系・限界値のテスト
・証跡もエクリプスの『JUnit』『カバレッジ』タブだけ
・次回改修のデグレ確認にも使える
軽く上げただけでもこんなにありますね。
ログインしてコメントを残そう!!


きっぷる
きっぷる