JUnitとは?
JUnitはJava言語向けの最も広く使われているユニットテストフレームワークです。JUnit 5(Jupiter)は最新バージョンで、モジュラーアーキテクチャ、ラムダ式対応、豊富なアサーションなど、現代的な機能を提供します。
JUnit 5
単体テスト
Java
基本アサーション
assertEquals / assertNotEqualsは最も頻繁に使用するアサーションです
// 値の一致検証
assertEquals(expected, actual);
assertEquals(expected, actual, "失敗時メッセージ");
// 値の不一致検証
assertNotEquals(unexpected, actual);
// 真偽値検証
assertTrue(condition);
assertFalse(condition);
// null検証
assertNull(object);
assertNotNull(object);
// 同一性検証(同じインスタンス)
assertSame(expected, actual);
assertNotSame(unexpected, actual);
テストメソッドの基本
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;
class CalculatorTest {
@Test
void testAddition() {
Calculator calc = new Calculator();
int result = calc.add(2, 3);
assertEquals(5, result);
}
@Test
@DisplayName("2つの数値の減算を検証")
void testSubtraction() {
Calculator calc = new Calculator();
assertEquals(2, calc.subtract(5, 3));
}
}
● @Testでテストメソッドを宣言
● @DisplayNameで読みやすい名前を設定
ライフサイクルメソッド
class LifecycleTest {
@BeforeAll
static void initAll() {
// 全テスト実行前に1回だけ実行
}
@BeforeEach
void init() {
// 各テストメソッド実行前に実行
}
@Test
void test1() { }
@Test
void test2() { }
@AfterEach
void tearDown() {
// 各テストメソッド実行後に実行
}
@AfterAll
static void tearDownAll() {
// 全テスト実行後に1回だけ実行
}
}
● @BeforeAll/@AfterAllはstatic必須
● @BeforeEach/@AfterEachで初期化/後処理
例外 & タイムアウト
// 例外がスローされることを検証
@Test
void testException() {
Exception e = assertThrows(
IllegalArgumentException.class,
() -> calculator.divide(10, 0)
);
assertEquals("除数が0です", e.getMessage());
}
// 例外がスローされないことを検証
@Test
void testNoException() {
assertDoesNotThrow(() -> {
calculator.add(1, 2);
});
}
// タイムアウト検証
@Test
@Timeout(value = 1, unit = TimeUnit.SECONDS)
void testTimeout() {
// 1秒以内に完了しないとFail
heavyProcess();
}
パラメータ化テスト
@ValueSource
@ParameterizedTest
@ValueSource(ints = {1, 2, 3, 5, 8})
void testPositive(int num) {
assertTrue(num > 0);
}
@ParameterizedTest
@ValueSource(strings = {"", " "})
void testBlank(String str) {
assertTrue(str.isBlank());
}
単一パラメータの複数値テスト
@CsvSource
@ParameterizedTest
@CsvSource({
"1, 2, 3",
"5, 3, 8",
"10, -2, 8"
})
void testAdd(int a, int b, int expected) {
assertEquals(expected, calc.add(a, b));
}
CSV形式で複数パラメータを渡す
@MethodSource
@ParameterizedTest
@MethodSource("provideTestData")
void testMultiple(String input, int expected) {
assertEquals(expected, input.length());
}
static Stream provideTestData() {
return Stream.of(
Arguments.of("abc", 3),
Arguments.of("hello", 5)
);
}
メソッドでテストデータを提供
@EnumSource
@ParameterizedTest
@EnumSource(Status.class)
void testEnum(Status status) {
assertNotNull(status.getCode());
}
enum Status { ACTIVE, INACTIVE }
Enum値をパラメータとして使用
高度なアサーション
assertAll
@Test
void testPerson() {
Person p = new Person(
"Taro", "Tokyo"
);
assertAll(
() -> assertEquals("Taro",
p.getName()),
() -> assertEquals("Tokyo",
p.getCity())
);
}
複数検証を一度に実行
コレクション検証
@Test
void testList() {
List expected =
List.of("a", "b");
List actual =
service.getList();
assertIterableEquals(
expected, actual
);
}
リスト/コレクションの比較
配列検証
@Test
void testArray() {
int[] expected = {1, 2, 3};
int[] actual =
service.getArray();
assertArrayEquals(
expected, actual
);
}
配列の要素比較
よく使うアノテーション
@Disabled
@Test
@Disabled("修正中")
void testSkip() {
// 実行をスキップ
}
@RepeatedTest
@RepeatedTest(10)
void testRepeat() {
// 10回繰り返し実行
}
@Tag
@Test
@Tag("integration")
void testIntegration() {
// タグ付けして分類
}
@Nested
@Nested
class InnerTests {
@Test
void test() {}
}
Maven/Gradle依存関係
Maven (pom.xml)
org.junit.jupiter
junit-jupiter
5.10.0
test
Gradle (build.gradle)
dependencies {
testImplementation(
'org.junit.jupiter:junit-jupiter:5.10.0'
)
}
test {
useJUnitPlatform()
}
実務で役立つTips
命名規則
テストメソッド名は「test + 対象メソッド名 + 条件」で統一すると可読性が向上します。
AAA パターン
Arrange(準備)、Act(実行)、Assert(検証)の3段階でテストを構造化しましょう。
境界値テスト
0, 負数, 最大値など境界値を必ずテストし、エッジケースを網羅しましょう。
カバレッジ
JaCoCo等でコードカバレッジを計測し、80%以上を目標にしましょう。
テスト実行順序
1
@BeforeAll
2
@BeforeEach
3
@Test
4
@AfterEach
5
@AfterAll
@BeforeEach/@AfterEachは各テストメソッドごとに実行されます