JUnit
JUnit とは
JUnit は、Java アプリケーションのユニットテスト(単体テスト)を記述・実行するためのフレームワークである。ユニットテストとは、メソッドやクラスといった小さな単位のコードが期待通りに動作するかを自動的に検証するテストのことを指す。現在の主流は JUnit 5(JUnit Jupiter)であり、アノテーションベースのテスト記述と豊富なアサーション機能を提供している。
なぜ SIer で重要か
SIer の開発プロジェクトでは、品質保証の一環としてユニットテストの実施が必須とされていることが多い。「カバレッジ(テストでどれだけのコードが実行されたか)80% 以上」といった基準が設けられ、テスト結果のエビデンス(証拠)を残すことが求められる。JUnit はこの品質基準を満たすための基盤ツールであり、SIer の Java 開発者にとって避けて通れない技術である。
基本概念
テストクラスとテストメソッド
JUnit では、テスト対象のクラスに対応するテストクラスを作成し、その中にテストメソッドを記述する。
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CalculatorTest {
@Test
void 正の数同士の加算() {
Calculator calc = new Calculator();
int result = calc.add(2, 3);
assertEquals(5, result);
}
@Test
void ゼロを加算した場合は元の値が返る() {
Calculator calc = new Calculator();
int result = calc.add(7, 0);
assertEquals(7, result);
}
}
@Test アノテーションが付いたメソッドがテストメソッドとして認識される。assertEquals はアサーション(検証)メソッドで、期待値と実際の値が一致するかを確認する。
主なアサーション
| メソッド | 検証内容 |
|---|---|
assertEquals(expected, actual) | 値が等しいことを検証 |
assertNotEquals(unexpected, actual) | 値が等しくないことを検証 |
assertTrue(condition) | 条件が true であることを検証 |
assertFalse(condition) | 条件が false であることを検証 |
assertNull(object) | オブジェクトが null であることを検証 |
assertNotNull(object) | オブジェクトが null でないことを検証 |
assertThrows(ExceptionClass, executable) | 特定の例外がスローされることを検証 |
テストライフサイクル
JUnit 5 では、テストの前後に実行される処理をアノテーションで定義できる。
class UserServiceTest {
@BeforeAll
static void 全テスト前に1回実行() {
// テスト全体の初期化(DB接続プールの作成等)
}
@BeforeEach
void 各テスト前に毎回実行() {
// テストごとの初期化(テストデータの投入等)
}
@Test
void テストメソッド() {
// テスト本体
}
@AfterEach
void 各テスト後に毎回実行() {
// テストごとのクリーンアップ
}
@AfterAll
static void 全テスト後に1回実行() {
// テスト全体のクリーンアップ
}
}
| アノテーション | 実行タイミング |
|---|---|
@BeforeAll | テストクラス内の全テストの前に 1 回だけ実行 |
@BeforeEach | 各テストメソッドの前に毎回実行 |
@AfterEach | 各テストメソッドの後に毎回実行 |
@AfterAll | テストクラス内の全テストの後に 1 回だけ実行 |
JUnit 4 と JUnit 5 の違い
SIer の既存プロジェクトでは JUnit 4 が使われていることもあるため、主な違いを把握しておく必要がある。
| 項目 | JUnit 4 | JUnit 5 |
|---|---|---|
| パッケージ | org.junit | org.junit.jupiter.api |
| テストアノテーション | @Test | @Test(import 元が異なる) |
| 初期化 | @Before / @After | @BeforeEach / @AfterEach |
| クラス初期化 | @BeforeClass / @AfterClass | @BeforeAll / @AfterAll |
| 例外テスト | @Test(expected = ...) | assertThrows() |
| アクセス修飾子 | public が必須 | public は不要(パッケージプライベートで可) |
JUnit 5 は JUnit 4 と比較してアノテーション名がより直感的になり、パラメータ化テストや条件付き実行など新機能も追加されている。
Mockito との組み合わせ
実際のプロジェクトでは、テスト対象のクラスが他のクラス(データベースアクセス、外部 API 呼び出し等)に依存していることが多い。Mockito は、これらの依存クラスの「モック(偽物)」を作成し、依存先の動作をシミュレートすることでテスト対象のクラスだけを検証できるようにするライブラリである。
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
@ExtendWith(MockitoExtension.class)
class OrderServiceTest {
@Mock
private OrderRepository orderRepository; // モック(偽物)
@InjectMocks
private OrderService orderService; // テスト対象
@Test
void 注文IDで注文を取得できる() {
// モックの振る舞いを定義
Order expected = new Order(1L, "商品A");
when(orderRepository.findById(1L)).thenReturn(expected);
// テスト実行
Order result = orderService.getOrder(1L);
// 検証
assertEquals("商品A", result.getName());
verify(orderRepository).findById(1L); // モックが呼ばれたことを検証
}
}
@Mock で依存先のモックを作成し、when(...).thenReturn(...) でモックの戻り値を定義する。これにより、データベースに接続せずに Service 層のロジックだけをテストできる。
SIer での使われ方
カバレッジ基準
SIer のプロジェクトでは、テストカバレッジ(テストで実行されたコードの割合)の基準が設けられていることが多い。
| カバレッジ指標 | 内容 | SIer での一般的な基準 |
|---|---|---|
| C0(命令網羅) | すべてのステートメントが 1 回以上実行されたか | 80% 以上 |
| C1(分岐網羅) | すべての分岐(if の true / false)が実行されたか | 要件に応じて設定 |
カバレッジの計測には JaCoCo というツールがよく使われ、Maven や Gradle のビルド時に自動的にレポートを生成する設定が組み込まれていることが多い。
テストエビデンス
SIer の納品物には「テストエビデンス」が含まれることが一般的である。JUnit のテスト結果をレポートとして出力し、全テストが成功していることを証跡として残す。Maven の surefire-report プラグインや CI/CD ツールのテストレポート機能が活用される。
テスト設計書との対応
SIer のプロジェクトでは、テストコードを書く前に「単体テスト設計書」を作成し、テストケース(テスト条件、入力値、期待結果)を Excel 等で一覧化することが多い。テストメソッド名をテストケース ID と対応させるなど、設計書とコードのトレーサビリティ(追跡可能性)を確保する工夫が求められる。
まとめ
- JUnit は Java のユニットテストフレームワークであり、現在の主流は JUnit 5 である
@Testでテストメソッドを定義し、assertEquals等のアサーションで期待結果を検証する- Mockito を組み合わせることで、依存先をモック化して対象クラスだけを独立してテストできる
- SIer の現場ではカバレッジ基準(例: C0 80% 以上)が設けられ、テストエビデンスの提出が求められることが多い
- JUnit 4 と JUnit 5 ではアノテーション名や記述方法に違いがあるため、既存プロジェクトのバージョンを確認することが重要