「動くことは動く。でも、直したところが他を壊していないか、実は自信がない」。そう感じたことがあるなら、原因はテストがないことだ。
JUnit5を使えば、@Testと数行のアサーションだけで、この不安を毎回機械的に確認できるようになる。
JUnit5の使い方は、(1) Maven/Gradleに依存関係を追加する、(2) src/test/javaに@Test付きのテストクラスを書く、(3) mvn testかIDEで実行して結果を確認する、の3ステップだ。
本記事では3ステップを順に解説したうえで、例外テスト・Arrange-Act-Assertによるテスト設計・Mockitoを使ったモック化まで、実務でそのまま使える形で扱う。
JUnit4からの変更点も押さえているので、既存プロジェクトでの移行判断にも使える。
JUnit5の書き方早見表(コピペ用)
テストを書くたびに「あのアノテーション、何だっけ」となるものを1つの表にまとめた。ブックマークしておけば、次からはこの表だけで足りる。
assertEquals 以外のアサーション(assertAll・assertTimeout など)は、JUnit assertメソッド一覧の早見表にまとめてある。
JUnit5とは?JUnit4との違いも解説
JUnitは、Javaのユニットテスト(単体テスト)を書いて実行するためのフレームワークです。Javaのテストツールとして最も広く使われています。
JUnitは高品質なソフトウェア開発に欠かせません。 コードが意図通りに動くかを自動で検証でき、バグの早期発見やリファクタリング(コードの改善作業)を支援してくれるからです。
ユニットテストの目的と重要性
ユニットテストの目的は、クラスやメソッドといったプログラムの最小単位(ユニット)が、それぞれ正しく動くかを確かめることです。
ユニットテストを導入するメリットは主に3つです。
この「仕様のドキュメント化」というメリットは、筆者自身、前任者が退職しドキュメントがほぼゼロの状態でシステムを引き継いだときに実感したことだ。
仕様書はなく、頼れるのはコードだけ。
それでもテストコードが残っていたクラスは、半年かけての引き継ぎ作業の中でも「どう動くべきか」が読むだけでわかり、把握のスピードが明らかに違った。
テストコードがなければ、仕様の把握はもっと長引いていたはずだ。
JUnitの概要とバージョンの違い(JUnit4とJUnit5)
JUnitにはいくつかのバージョンがありますが、現在主流なのはJUnit5です。以前はJUnit4が広く使われていました。
JUnit4とJUnit5では、アーキテクチャとアノテーション名が大きく変わりました。
例えば、テスト前の初期化処理は、JUnit4では@Beforeでしたが、JUnit5では@BeforeEachに変わりました。
JUnit5は、JUnit Platform・JUnit Jupiter・JUnit Vintageの3つのモジュールに分かれました。
テストを動かす土台(Platform)と書き方(Jupiter)が分離されたため、拡張しやすくなっています。
JUnit6は2025年9月30日に正式リリース(GA)されました。以降の修正版は公式のリリースノートで確認できます。
一方のJUnit5も、2026年4月に5.14.4が出るなど保守リリースが続いています。
ただし、Java17以上が必須になったことや既存プロジェクトの移行コストから、実務では引き続きJUnit5(Jupiter)が広く使われています。
これから初めてJavaのテストを学ぶなら、まずはJUnit5から始めるのが現実的です。
JUnit4とJUnit5の主な違いを表にまとめました。
JUnit4からJUnit5への移行手順
既存プロジェクトでJUnit4からJUnit5に移行する場合、以下の手順で進めます。
- 依存関係の変更:
pom.xml/build.gradleからjunit:junitを削除し、junit-jupiter-api・junit-jupiter-engineに置き換えます。 - 段階的な移行:
junit-vintage-engineを依存関係に追加すれば、既存のJUnit4形式のテストを残したまま、新規テストだけJUnit5で書けます。テストを一度に全て書き直す必要はありません。 - アノテーション名の一括置換:
@Before→@BeforeEach、@BeforeClass→@BeforeAllなど、上記の比較表に沿ってIDEの一括置換機能で変更します。 - ランナーの置き換え: Spring Bootプロジェクトなどで
@RunWith(SpringRunner.class)を使っている場合は置き換えが必要です。JUnit5では@RunWith自体が廃止されたため、@ExtendWith(SpringExtension.class)を使います。
JUnit5の導入方法(Maven/Gradle)
JUnitをプロジェクトに導入するのは簡単です。
特に、MavenやGradleといったビルドツールを利用すると、数行の設定を追加するだけで済みます。
Maven/Gradleによる導入
最近のJavaプロジェクトでは、依存ライブラリの管理にMavenまたはGradleを使用するのが一般的です。
Mavenの場合 (pom.xml)
pom.xmlファイルの<dependencies>セクションに、以下の依存関係を追加します。
<scope>test</scope>は、このライブラリがテストコードのコンパイルと実行時にのみ必要であることを示します。
JUnit5はJava 8以上で動作します。
2026年現在の最新LTSはJava 25(2025年9月リリース)で、Java 21 LTSと並んで実務の主流です。
次期LTSはJava 29(2027年9月予定)です。
Gradleの場合 (build.gradle)
build.gradleファイルに以下を記述します。Gradle 9以降は junit-platform-launcher を宣言しないとテストが起動しないため、この行も忘れずに入れてください。
IDE(IntelliJ/Eclipse)でのセットアップ
IntelliJ IDEA・Eclipse・VS Code(Extension Pack for Java)などのIDEを使っている場合、さらに簡単です。
たとえばIntelliJ IDEAでGradleプロジェクトを新規作成すると、通常はJUnitの依存関係が最初から入っています(Mavenプロジェクトや入っていない場合は上記の依存関係を追加します)。
テストクラスを手動で作る場合も、IDEがJUnitの追加を提案してくれます。
JUnit5の基本的なテストの書き方
導入が終わったら、ここからはテストコードを書きます。
ここでは、計算を行うシンプルなCalculatorクラスを例に、基本的なテストの書き方を解説します。
@Testアノテーションの使い方
JUnit5では、テスト用に書いたメソッドに@Testアノテーションを付けると、JUnitがそのメソッドをテストケースとして実行します。
テストクラスは、慣習としてsrc/test/javaディレクトリ配下に作成します。
アサーション(assertEquals / assertTrueなど)
テストコードの核心は「アサーション(Assertion)」、つまりメソッドの実行結果が期待どおりかを検証する仕組みです。
JUnit5ではAssertionsクラスのstaticメソッドを使います。
最もよく使われるのが、2つの値が等しいかを確認するassertEqualsです。
assertEqualsは、第1引数に「期待値」、第2引数に「実際の値」を取ります。
第3引数は、テストが失敗したときに表示されるメッセージで、省略できます。
他にも、以下のような便利なアサーションメソッドがあります。
assertAllやassertIterableEqualsを含む全メソッドの使い分けは、JUnitのassertメソッド一覧(早見表)にまとめています。
例外の検証
特定の条件下で、メソッドが正しく例外をスローするかを検証したいケースもあります。
JUnit5では、assertThrowsメソッドを使って簡単に例外テストを記述できます。
assertThrowsの第1引数には期待する例外の型、第2引数には例外が出るはずの処理をラムダ式で渡します。
意図した例外が正しく発生するかを安全にテストできます。
テストの実行方法(Maven/Gradle/IDE)
テストは書いただけでは動きません。ビルドツールのコマンドかIDEから実行して、はじめて結果がわかります。
コマンドラインで実行する場合は、プロジェクトのルートディレクトリで次のように入力します。
Mavenで実行すると、最後に次のような集計行が表示されます。
FailuresとErrorsが0なら全テスト成功です。Failuresはアサーションの不一致、Errorsは想定外の例外、Skippedは@Disabledなどで飛ばしたテストの件数を表します。
「Tests run: 0」と表示されてテストが見つからない場合は、MavenのSurefireプラグインが古い可能性があります。JUnit5のテストを実行するには、maven-surefire-pluginを2.22.0以上(できれば3系)に上げてください。
IDEから実行する場合、IntelliJ IDEAはテストクラスやメソッドの横にある実行ボタン(▶)をクリックします。Eclipseはテストクラスを右クリックし、[実行]→[JUnitテスト]を選びます。
どちらも結果は緑(成功)・赤(失敗)で一覧表示されます。
テストケースの構造と設計
読みやすく保守しやすいテストを書くには、構造と命名が大切です。3つのポイントを紹介します。
Arrange-Act-Assertパターンとは
テストコードはArrange-Act-Assert (AAA) パターンで書くのが効果的です。 テストの目的が明確になり、誰が見てもわかりやすくなります。
Arrange・Act・Assertの3フェーズをコメントや空行で明確に分けることで、どこで何を確かめているテストなのかが一目でわかります。
実務でよくある失敗は、1つのテストメソッドに複数のActとAssertを詰め込むことです。テストが失敗したとき、どのActが原因かわからなくなります。
1テスト1検証を心がけましょう。
テストクラスとテストメソッドの命名規則
テストメソッドの命名で理想的なのは、名前を読むだけで「何を」「どの状況で」「どう検証しているか」がわかることです。
- テストクラス名:
[テスト対象クラス名]Testとするのが一般的です。(例:CalculatorTest) - テストメソッド名: 英語なら
should[期待する結果]When[条件]のような形式があります。日本語なら「〇〇の場合は〇〇を返すこと」のように自然な文章で書くとわかりやすいです。
良い命名は、テストが失敗したときのエラーメッセージを読むだけで、問題の原因を推測する手助けとなります。
筆者のチームでは、日本語メソッド名を採用しています。IDEのテスト結果が一目で読めるため、コードレビューの効率が上がりました。
英語名か日本語名かはチームで統一することが大切です。
ユニットテスト(単体テスト)と統合テストの違い
JUnitが得意とする「ユニットテスト(単体テスト)」は、クラスやメソッドなど1つの部品を対象にします。
データベースやAPIなど外部への依存を切り離し、対象のロジックだけを検証します。
一方、「統合テスト」は複数のコンポーネントを組み合わせ、連携が正しく動くかを確認します。
ControllerからServiceを経由してDBにアクセスする一連の流れが典型例です。
まずはユニットテストをしっかり書くことが、品質保証の第一歩です。
ただし、ユニットテストだけでは検知できない不具合もある。
以前、同一クラス内のメソッド呼び出しでは@Transactionalが効かない(プロキシの限界)という問題に、本番でデータ不整合が発生して初めて気づいたことがある。
各メソッド単体のユニットテストはすべて通っていたのに、実際にサービス層を経由して呼び出す統合的な流れの中でだけ不具合が現れていた。
以降、サービス層の分割を徹底し、ユニットテストと統合テストの両方を書くようになった。
テストが失敗したら、どう確認する?
テストを書き始めたばかりの頃は、テストが失敗した理由を読み解くこと自体でつまずきがちです。ここでは失敗時の確認手順を整理します。
アサーションエラーの読み方
assertEqualsが失敗すると、次のようなメッセージが表示されます。
expected(期待値)とwas(実際の値)を見比べれば、どこがズレているかが一目でわかります。
assertEqualsの第3引数に渡したメッセージ(例:「2 + 3 は 5 になるべきです」)は、エラーの先頭に表示されます。
アサーションが複数あるテストほど、第3引数のメッセージを具体的に書いておくと原因を早く特定できます。
よくある失敗原因3パターン
IntelliJ IDEAやEclipseでは、テスト結果画面で失敗したテストをクリックすると、該当するアサーション行にジャンプできます。
まずはエラーメッセージのexpectedとwasを見比べ、次に上記3パターンに該当していないかを確認する、という順番で切り分けると効率的です。
JUnit5の便利なアノテーション
基本をマスターしたら、テストをさらに効率化するアノテーションを使いましょう。
@BeforeEach / @AfterEach(初期化と後処理)
@BeforeEachは、各テストの前に共通の初期化処理を実行するアノテーションです。複数のテストで同じオブジェクト生成が必要なときに役立ちます。
同様に、@AfterEachは各テストメソッドの実行後に呼ばれ、リソースの解放などの後処理に使います。
クラス全体で1回だけ実行したい処理には、@BeforeAllと@AfterAllを使います。DB接続の確立のような重い準備が典型例で、メソッドは原則staticにする必要があります。
4つのアノテーションが呼ばれる順番を図にすると、次のようになります。
@Testが2つあるクラスで呼ばれる順番
各段をタップすると、その時点までの実行回数とコンソール出力を確認できます。
JUnit5は標準ではテストメソッドごとにテストクラスのインスタンスを新しく作ります。そのため@BeforeEachで初期化したフィールドは、テスト間で状態が引き継がれません。
@ParameterizedTestによるパラメータ化テスト
同じロジックのテストを、異なる入力値と期待値で何度も実行したいケースは多い。
@ParameterizedTestを使うと、テストコードの重複を避けられます。
@ValueSourceを使えば、簡単な値のリストをパラメータとして渡せます。
なお、@ParameterizedTestや@ValueSourceはjunit-jupiter-paramsに含まれます。導入方法の節で示したjunit-jupiter-apiとjunit-jupiter-engineだけでは入らないため、org.junit.jupiter:junit-jupiter-params(バージョンは同じ5.14.4)もtestスコープで追加してください。
注意
この例で使ったString#isBlank()はJava 11以降のメソッドです。
Java 8環境ではinput.trim().isEmpty()に置き換えてください。
さらに、@CsvSourceを使えば、カンマ区切りの値で複数の引数(入力値と期待値など)を渡せます。
@DisplayNameでテスト名をわかりやすくする
JUnit5の@DisplayNameアノテーションを使うと、テスト結果のレポートに任意の名前を表示できます。
メソッド名が英語でも、レポートには日本語の説明を出せるので便利です。
テストメソッド名を日本語にする方法もありますが、@DisplayNameを使えばメソッド名は英語の命名規則に従いつつ、レポートだけ日本語にできます。
チーム開発ではこちらが推奨されるケースが多いです。
@Nestedによる階層的テスト構造
テスト対象クラスの機能が複雑になると、テストクラスも肥大化しがちです。
@Nestedアノテーションを使い、内部クラスでテストをグループ化すると、テストの構造がわかりやすくなります。
関連するテストをまとめると、テスト結果もグループ単位で表示されるため、どの機能のテストが落ちたかをすぐ追えます。
@Disabledでテストを一時的に無効化する
未実装の機能に対応するテストや、環境依存で一時的に実行できないテストは、削除せずに@Disabledで無効化しておくと、後で対応漏れを防げます。
@Disabledは前述の比較表にあるJUnit4の@Ignoreに対応するアノテーションです。
引数に無効化した理由を残しておくと、後でテストを見た人(未来の自分を含む)が状況を把握しやすくなります。
Mockitoを使ったモックテスト
実際の開発では、クラスが他のクラスや外部システム(データベース、APIなど)に依存していることがほとんどです。
依存先まで含めるとユニットテストの範囲を超えてしまいます。
そこで登場するのが「モック(Mock)」です。モックとは、本物のオブジェクトのふりをする偽物のオブジェクトのこと。
Mockitoなどのモックライブラリを使うと、モックを簡単に作成できます。
Mockitoの基本と導入方法
Mockitoは、Javaで最も人気のあるモックライブラリの一つです。
Mockitoを使うことで、依存オブジェクトの振る舞いを自由に定義し、テスト対象のロジックだけに集中できます。
導入はJUnitと同様に、ビルドツールに依存関係を追加するだけです。なお、Mockito 5系はJava 11以上が必要です(Java 8環境ではMockito 4系を使います)。
Mavenの場合 (pom.xml)
依存オブジェクトはどうモック化する?
例えば、ユーザー情報をUserRepositoryから取得して処理を行うUserServiceをテストしたいとします。
UserRepositoryはデータベースにアクセスするため、ユニットテストではモックに置き換えます。
Mockitoを使えば、次のようにテストを書けます。
UserServiceTestの中で起きていること
when(...).thenReturn(...)は、モックの振る舞い(スタブ:あらかじめ決めた値を返す設定)を定義するメソッドです。
verify(...)では、モックのメソッドが期待通りに呼ばれたかを検証します。
モックを使うことで、データベースに接続せずにUserServiceのロジックをテストできました。
モックを使うかどうかの判断基準はシンプルです。
テスト対象のロジックに集中したいとき、外部依存(DB・API・ファイルシステム)を切り離すためにモックを使います。
逆に、値の変換や計算だけを行うユーティリティクラスには、モックは不要です。
もう一つの判断軸として、「モックの数が増えすぎていないか」も見ておきたい。
1つのテストのために何個も@Mockを用意しなければならないなら、問題はテストの書きにくさだけではない。
テスト対象クラスが多くのクラスに依存しすぎている、という設計上のサインであることが多い。
モックが増えて辛くなったら、まずクラス設計を疑ってみる価値がある。
ここで紹介したのはMockitoの導入部分のみだ。spy・doReturn・ArgumentCaptorによる引数検証や静的メソッドのモック化は扱っていない。
Spring Bootの@MockitoBeanへの移行まで含めた内容は、Mockitoの使い方を解説した別記事で扱っている。
よくある質問
Q1. JUnit5とJUnit4の違いは何ですか?
A1. 最大の違いはアーキテクチャとアノテーション名です。JUnit4は単一jarでしたが、JUnit5はPlatform・Jupiter・Vintageの3モジュール構成になりました。初期化処理も@Before(JUnit4)から@BeforeEach(JUnit5)に変わっています。
Q2. JUnit5はどうやって導入しますか?
A2. MavenまたはGradleの依存関係にjunit-jupiter-apiとjunit-jupiter-engineを追加します(Gradleではjunit-platform-launcherも追加)。IntelliJ IDEAでGradleプロジェクトを新規作成した場合は、通常JUnitの依存関係が最初から入っています。
Q3. JUnit5でモックを使うにはどうすればいいですか?
A3. Mockitoライブラリを使います。@ExtendWith(MockitoExtension.class)でMockito拡張を有効にし、@Mockでモックを作成、@InjectMocksでテスト対象に注入します。外部依存(DB・APIなど)を切り離したいときに使います。
Q4. パラメータ化テストとは何ですか?
A4. 同じロジックを異なる入力値・期待値で繰り返しテストする仕組みです。JUnit5では@ParameterizedTestと@ValueSourceや@CsvSourceを組み合わせて使うと、テストコードの重複を避けられます。
Q5. @DisplayNameは何のために使いますか?
A5. テスト結果のレポートに任意の名前を表示するためのアノテーションです。メソッド名は英語の命名規則に従いつつ、レポートだけ日本語の説明にできるため、チーム開発で推奨されるケースが多いです。
Q6. テストを一時的にスキップするにはどうすればいいですか?
A6. @Disabledアノテーションを使います。JUnit4の@Ignoreに対応するもので、引数に無効化した理由を残しておけば、未実装機能や環境依存のテストを削除せずに一時停止できます。
Q7. JUnit6が出た今でもJUnit5を学ぶべきですか?
A7. はい、現実的な選択です。JUnit6は2025年9月30日に正式リリースされましたが、Java17以上が必須になったことや既存プロジェクトの移行コストから、2026年時点でも実務ではJUnit5(Jupiter)が広く使われています。
Q8. ユニットテストと統合テストの違いは何ですか?
A8. ユニットテストはクラスやメソッドなど1つの部品を対象に、外部依存を切り離してロジックだけを検証します。統合テストは複数のコンポーネントを組み合わせ、連携が正しく動くかを確認します。両方を書くことで、単体では見えない不具合も検知できます。
まとめ
JUnitによるユニットテストは、Javaエンジニアの必須スキルです。
使い方の流れは、冒頭で示した3ステップに集約されます。依存関係を追加し、@Testとアサーションでテストを書き、mvn testやIDEで実行して結果を確認する。まずは手元のクラス1つで、この流れを一周させてみてください。
JUnitを使うと得られるメリット
- コードの品質が向上する: 自動化されたテストが、バグの混入を未然に防ぎます。
- 開発速度が上がる: 手動テストの時間を削減し、問題の早期発見により手戻りを減らせます。
- 自信を持って開発できる: テストという安全網があるため、リファクタリングや機能追加を恐れずに行えます。
- 仕様が明確になる: テストコードが、コードの振る舞いを定義するドキュメントとして機能します。
最初はテストコードに時間がかかります。
それでも、テストに使った時間は、修正のたびに手動確認を繰り返す手間の削減と、デグレードの早期発見という形で返ってきます。
JUnit5の基本を理解したら、次はSpring Boot 4での統合テスト(@SpringBootTest)や、カバレッジ計測ツール(JaCoCo)に挑戦してみてください。
| REV. | DATE | 内容 |
|---|---|---|
| 4 | 2026-10-04 | 記載内容の事実確認と修正 |
| 3 | 2026-08-21 | 2026年8月時点の情報で全体を見直し(古い記述を6件更新) |
| 2 | 2026-05-21 | 2026年5月時点の情報で全体を見直し |
| 1 | 2025-07-30 | 初版 |




