📝

Javaの単体テスト関連メモ

2023/03/18に公開

Javaの単体テスト関連のメモ

Javaのテスト書いた時の色々メモ

使用したライブラリ
・テストフレームワーク
JUnit 5.8.2
・モックライブラリ
Mockito 4.0.0

通常のケース

xUnit系でよくあるassert○○で検証

@Test
void テスト関数() {
    // テスト対象を生成して処理を実行する関数を呼び出し
    var sut = new SystemUnderTestClass();
    var result = sut.doSomething("param", "1");
    // 結果を検証
    assertEquals("param1", result);

    // 他の検証方法(例)
    assertTrue(result == "param1");
    assertThat(result, is("param1"));

}

パラメーター化テスト

引数の違いのみの場合に、データ毎のテストを用意せずに1つのテスト関数でまとめて書く場合

@ParameterizedTest
@ValueSource(ints = {2,4,6,8})
void 偶数(int number) {
    var sut = new SystemUnderTestClass();
    assertTrue(sut.isEven(number));
}

// CSV 形式で指定
@ParameterizedTest
@CsvSource({
    "1,false",
    "2,true",
    "3,false",
    "4,true"
})
void 偶数かの判定(int number, Boolean expexted) {
    var sut = new SystemUnderTestClass();
    assertEquals(expexted, sut.isEven(number));
}

データの生成処理(独自のクラスなど)が必要な場合はMethodSourceを使用

@ParameterizedTest
@MethodSource("getTestParams")
void 文字列を1文字ずつ分割(String param, String[] expected) {
    var sut = new SystemUnderTestClass(param);
    var result = sut.split();

    assertArrayEquals(expectedKeyList, result);

}
static Stream<Arguments> getTestParams() {
    return Stream.of(
        Arguments.of("test", new String[] { "t","e","s","t" }),
        Arguments.of("abcd", new String[] { "a","b","c","d" }),
}

モック

(springboot入れてると依存がらみでMockitoがついてくるもよう)

@Test
void 外部APIの実行() {
    // モックの生成
    var mock = Mockito.mock(APIClient.class);
    when(mapperMock.sendData(anyInt())).thenReturn(200);
    // テスト対象クラス生成
    var sut = new SystemUnderTestClass(mock);
    // 実行
    sut.send();
    // 検証
    // 1 回呼ばれたことの検証
    verify(mapperMock, times(1)).sendData(1);
    // 対象ではないものが呼ばれていないことの検証
    verify(mapperMock, never()).getData(anyInt());
}

static メソッドのモック

「src/test/resources/mockito-extensions」フォルダを作成
作成したフォルダ内に以下ファイル名のファイルを作成
「org.mockito.plugins.MockMaker」
作成したファイルの先頭に「mock-maker-inline」と記載して保存
(依存関係にテストの依存として「'org.mockito:mockito-inline'」を追加することでも可能)

@Test
void 外部APIの実行() {
    // try-with-resourcesを使用しない場合は、テスト終了時にmock.close()を呼び出す必要がある
    try (MockedStatic<StaticAPIClient> mock = Mockito.mockStatic(StaticAPIClient.class)) {
        mock.when(() -> StaticAPIClient.send(any())).thenReturn(new Response(200));

        var sut = new SystemUnderTestClass(mock);
        var result = sut.send();

        mock.verify(() -> StaticAPIClient.send(any()), times(1));
        assertEquals(200, result);
    }
}

その他

他の書き方などは以下
junit
https://junit.org/junit5/docs/current/user-guide/
mockito
https://site.mockito.org/

Discussion