結論から言うと、JUnitのassertメソッドは目的で使い分けます。
値の比較にはassertEquals、真偽値やnullの判定にはassertTrue/assertNull、例外の検証にはassertThrows、複数条件をまとめて検証したいときはassertAllを使います。
迷ったらまずassertEqualsとassertThrowsを押さえれば、実務のテストコードの大半はカバーできます。
JUnitでテストを書いていて、assertEqualsとassertThat、結局どっちを使えばいいんだろう…って迷ったことありませんか?私も駆け出しのころは、ネットのサンプルコードを見るたびに違うメソッドが出てきて、正直「もうassertTrueで全部済ませちゃえ」と投げやりになった時期があります。
ただ、そのやり方だとテストが失敗したときにエラーメッセージが不親切で、原因を探すのに毎回時間を溶かしていました。
JUnitの主要なassertメソッドは、役割ごとに整理すれば迷わず選べます。
assertEquals・assertThat・assertThrowsを中心に、実際のコード例つきで見ていきましょう。
読み終わるころには、状況に応じて最適なassertを迷わず選べるようになります。
JUnitのassertとは?アサーションの基本
JUnitのassertとは、テストコード内で期待した値と実際の値が一致するかを検証する仕組みのことです。
この検証を「アサーション」と呼び、一致しなければテストは自動的に失敗します。
手動でif文を書いて確認するより圧倒的に少ないコード量で、しかも失敗理由まで出力してくれるのが強みです。
assertメソッドが担う役割
assertメソッドは、テスト対象のコードが仕様どおりに動いているかを機械的に判定する仕組みです。
目視での確認と違って人的ミスが起きにくく、CIに組み込めば毎回同じ基準でチェックできます。
私は昔、コンソール出力を目で見て「多分OK」と判断していましたが、微妙な誤差を何度も見逃して痛い目を見ました。
JUnit4/5/6でのassertの違い
JUnit4ではorg.junit.Assertクラス、JUnit5ではorg.junit.jupiter.api.Assertionsクラスにassertメソッドが定義されています。
地味だけど地雷なのが引数の順番です。
JUnit4はassertEquals(String message, expected, actual)とメッセージが先頭ですが、JUnit5はassertEquals(expected, actual, String message)で末尾に変わりました。
バージョン違いのコードをコピペすると、この順番ミスでハマりがちです。
ちなみに2025年9月にリリースされたJUnit6でも、assertメソッドは引き続きJUnit5と同じorg.junit.jupiter.api.Assertionsクラスに定義されています。
書き方に破壊的変更はありません。2026年8月時点の最新安定版は6.1.3(2026年8月7日リリース)です。
値の比較にはどのassertメソッドを使う?
値の一致・不一致を検証したいとき、まず候補に挙がるのがこのグループです。プリミティブ型からオブジェクト、配列まで幅広くカバーしています。
どれも書き方は似ていますが、対象のデータ型によって使うべきメソッドが変わるので、ここでしっかり整理しておきましょう。
assertEqualsで期待値と実際値を比較する
assertEqualsは期待値と実際値が等しいかを検証する、JUnitの中でもっとも使用頻度の高いメソッドです。
数値・文字列・オブジェクトなど幅広い型に対応しています。
@Test
void 合計金額が正しく計算されること() {
int actual = calculateTotal(1200, 3);
assertEquals(3600, actual, "合計金額の計算結果が一致しません");
}
第3引数のメッセージは省略可能ですが、私は基本的に入れる派です。
テストが数百件になってくると、メッセージなしでは「どのassertEqualsが落ちたのか」を探すだけで時間を食うようになります。
assertArrayEqualsで配列を比較する
配列はassertEqualsに渡しても参照比較になってしまい、中身が同じでも失敗します。
要素の中身を比較したい場合はassertArrayEqualsを使いましょう。
int[] expected = {1, 2, 3};
int[] actual = sortAscending(new int[]{3, 1, 2});
assertArrayEquals(expected, actual);assertNotEqualsで不一致を検証する
「絶対に等しくならないこと」を保証したい場面もあります。そんなときはassertNotEqualsの出番です。
IDの重複防止やキャッシュの更新確認など、意外と使いどころがあります。
assertNotEquals(oldToken, refreshToken(oldToken));真偽値・nullの判定に使うassertメソッド
条件式の真偽やnullの有無を確認したいときに使うグループです。値そのものの比較というより「状態」を検証する用途で活躍します。
フラグ管理や初期化処理のテストで頻出します。
assertTrue/assertFalseで条件を検証する
booleanを返す条件式をそのまま検証したいときに使います。
ただし何でもassertTrueに頼ると失敗時のメッセージが「trueであるべきがfalseでした」としか出ず、原因が分かりにくくなります。
可能ならassertEqualsなど専用メソッドを優先しましょう。
assertTrue(user.isActive());
assertFalse(user.isLocked());assertNull/assertNotNullでnullを判定する
初期化前の変数や、検索結果が見つからなかった場合の戻り値検証によく使います。
nullチェックの漏れはNullPointerExceptionの温床になるので、ここは丁寧にテストしておく価値があります。
assertNull(repository.findById(999));
assertNotNull(repository.findById(1));assertThrowsで例外発生をテストする方法
異常系のテストは正常系より後回しにされがちですが、実は事故を防ぐうえで一番効きます。
JUnit5ではassertThrowsを使うことで、例外の発生と型を1行で検証できます。
assertThrowsの基本的な書き方
第1引数に期待する例外クラス、第2引数にテスト対象の処理をラムダ式で渡します。指定した例外が発生しなければ、この行自体がテスト失敗になる仕組みです。
@Test
void 在庫が不足していると例外が発生すること() {
IllegalStateException exception = assertThrows(
IllegalStateException.class,
() -> order.reserve(999)
);
assertEquals("在庫が不足しています", exception.getMessage());
}戻り値で例外オブジェクトを受け取れるので、メッセージの中身まで検証できるのが便利なところ。
JUnit4時代のtry-catchでfail()を書いていた頃と比べると、圧倒的にすっきり書けます。
assertDoesNotThrowで例外なしを確認する
逆に「例外が発生しないこと」を明示的にテストしたい場合はassertDoesNotThrowを使います。
リファクタリング後に想定外の例外が混ざっていないかを確認するのに向いています。
assertDoesNotThrow(() -> order.reserve(1));assertThat非推奨とAssertJの代替
「assertThatで検索したのにJUnit5では見つからない」と混乱した経験がある人は多いはずです。
結論から言うと、JUnit5の標準にassertThatは含まれておらず、使いたい場合はAssertJへの乗り換えが基本の選択肢になります。
assertThatの扱いは誤解されやすいポイントなので、丁寧に整理します。
JUnit5でassertThatが使えない理由
JUnit4のassertThatはHamcrestライブラリのMatcherに依存したメソッドでした。
JUnit5のAssertionsクラスには、このassertThatは含まれていません。つまり非推奨というより、標準機能としては廃止された状態です。
使いたい場合はHamcrestを別途依存に追加するか、後述のAssertJに乗り換える必要があります。
代替となるAssertJの書き方
私は今のプロジェクトではAssertJを使っています。理由はシンプルで、メソッドチェーンで読みやすく、IDEの補完も効きやすいからです。
import static org.assertj.core.api.Assertions.assertThat;
assertThat(actual).isEqualTo(5);
assertThat(userList).hasSize(3).contains("山田");assertEqualsだと1つの条件ごとに1行必要ですが、AssertJならメソッドチェーンで複数条件をつなげられます。
可読性を重視するチームなら検討する価値があるはずです。
複数のassertをまとめるassertAllの使い方
assertメソッドは通常、最初に失敗した時点で処理が止まります。
1つのテストで複数項目を確認したい場合、この仕様だと後続のチェックが実行されずもどかしいものです。
assertAllを使えば、最後まで実行してから失敗をまとめて報告する挙動に変えられます。
assertAllで一括検証するメリット
assertAllにラムダ式のグループを渡すと、途中で失敗があっても最後まで実行し、失敗したものをまとめて報告してくれます。
1回のテスト実行で複数の不具合箇所が分かるので、修正のたびに何度もテストを回す手間が減ります。
@Test
void ユーザー情報が正しく登録されること() {
User user = userService.findById(1);
assertAll("user",
() -> assertEquals("山田太郎", user.getName()),
() -> assertEquals("yamada@example.com", user.getEmail()),
() -> assertTrue(user.isActive())
);
}エラーメッセージを分かりやすくするコツ
assertAllの第1引数にはグループ名を渡せます。
ここにテスト対象の文脈が分かる文字列を入れておくと、CIのログを見ただけで「どの機能で落ちたか」が一目で分かるようになります。
地味ですが、チーム開発では効いてくる工夫です。
assertが失敗したときによくあるエラーと対処法
ここまででassertメソッドの使い分けは一通り押さえました。
ただ、実際にテストを書き始めると、今度は失敗したときのエラーメッセージの読み方でつまずくことが多いはずです。
expected: <...> but was: <...>という表示を見て、どちらが期待値でどちらが実際の値なのか一瞬迷った経験は誰にでもあります。
結論としてはexpectedが本来こうあってほしい値、was(またはactual)がコードの実行結果です。
ここを取り違えたまま原因を追うと、直すべきコードとテストコードを逆に修正してしまうことがあるので注意してください。
org.opentest4j.AssertionFailedError:
expected: <3600> but was: <3500>NullPointerExceptionでテストが落ちるケースも頻出です。
比較対象がそもそもnullなのに気づかずassertEqualsを呼んでしまうと、アサーション自体ではなくその手前で例外が発生します。
この場合は先にassertNotNullで対象がnullでないことを確認してから、本来検証したい値をassertEqualsで比較する2段構えにすると、失敗の原因を「nullだったのか」「値が違ったのか」で切り分けられます。
正直に言うと、新人時代の私は1日10回以上NullPointerExceptionを出していました。
assertNotNullで事前に切り分ける癖がついてから、この手のエラーで路頭に迷う時間は目に見えて減りました。
「値は同じはずなのになぜか失敗する」というケースもあります。
doubleやfloatの計算結果を、丸め誤差を考慮せずassertEqualsで直接比較してしまった場合に起きがちです。
doubleやfloatの比較には許容誤差(delta)を指定できるオーバーロードがあるので、そちらを使うと解決します。
オブジェクト同士の比較で常に失敗する場合は、比較対象のクラスにequals()が実装されているか(あるいは全フィールドを正しく比較できているか)を疑ってみてください。
IDEでテストを実行している場合は、失敗したテストの詳細画面に「Expected」と「Actual」を並べた差分表示が出ます。
まずはそこで期待値と実際値のどちらがおかしいかを確認してください。
次に、どのassertメソッドがどの引数の順番で呼ばれているかをコードで確認しましょう。この順番で追うと迷いにくくなります。
その他によく使うassertメソッド
ここまでで紹介しきれなかったものの、実務で意外と出番があるassertメソッドを3つ補足しておきます。
頻度は低めですが、知らないと遠回りな検証コードを書いてしまいがちなメソッドたちです。
assertSameで参照の同一性を確認する
assertEqualsが「値が等しいか」を見るのに対し、assertSameは「同一インスタンスかどうか」を検証します。
シングルトンやキャッシュされたオブジェクトが使い回されているかを確認したいときに向いています。
User instance1 = UserCache.get(1);
User instance2 = UserCache.get(1);
assertSame(instance1, instance2);assertTimeoutで処理時間を検証する
処理が想定時間内に終わることを保証したいときに使います。
assertTimeoutPreemptivelyは制限時間を超えた瞬間に処理を強制打ち切るため、無限ループの検知にも使えます。
パフォーマンス劣化を早期に発見する目的で組み込むと安心です。
assertTimeout(Duration.ofMillis(200), () -> heavyCalculation());
assertTimeoutPreemptively(Duration.ofMillis(200), () -> heavyCalculation());fail()でテストを意図的に失敗させる
未実装のテストケースに仮置きしたり、到達すべきでない分岐に処理が来たことを検知したりする用途で使います。
TODOコメントだけ書いて放置するより、fail()を仕込んでおけば実行時に気づける分だけ安全です。
@Test
void 未実装のテスト() {
fail("まだ実装していません");
}よくある質問(FAQ)
Q1. assertEqualsとassertThatはどちらを使うべきですか?
JUnit5では標準にassertThatが含まれないため、基本はassertEqualsで十分です。複数条件をまとめて読みやすく書きたい場合は、AssertJのassertThatを別途導入するのがおすすめです。
Q2. assertThrowsで例外のメッセージまで検証できますか?
できます。assertThrowsの戻り値として例外オブジェクトを受け取れるので、getMessage()の値をassertEqualsで確認すれば大丈夫です。
Q3. assertTrueばかり使うのはよくないですか?
動作はしますが、失敗時のメッセージが分かりにくくなるためおすすめしません。可能な限りassertEqualsやassertNullなど、目的に合った専用メソッドを選びましょう。
Q4. JUnit4のassertとJUnit5のassertは混在できますか?
技術的には両方のライブラリを依存に含めれば動きますが、引数の順番が異なるため事故のもとです。プロジェクト内ではどちらか一方に統一することを強くおすすめします。
Q5. assertAllを使うと処理速度は遅くなりますか?
体感できるほどの差はありません。それより一度の実行で複数の不具合を発見できるメリットのほうが、開発効率の面で大きいです。
Q6. 配列ではなくListを比較したいときは何を使いますか?
assertIterableEqualsを使います。ListやSetなどIterableを実装したコレクション同士を、要素の中身で比較できます。
まとめ|assertメソッドの使い分け早見表
ここまでJUnitの主要なassertメソッドを見てきました。最後に、目的別の使い分けを一覧で整理しておきます。
| 目的 | 使うメソッド | ポイント |
|---|---|---|
| 値の一致を確認 | assertEquals | もっとも汎用的、まず候補にする |
| 配列の中身を比較 | assertArrayEquals | 参照比較にならないよう専用メソッドを使う |
| 条件式の真偽 | assertTrue / assertFalse | 多用するとメッセージが分かりにくい |
| nullの有無 | assertNull / assertNotNull | NullPointerException対策に有効 |
| 例外の発生 | assertThrows | 戻り値でメッセージまで検証できる |
| 複数条件の一括検証 | assertAll | 途中で止まらず全件報告してくれる |
| 読みやすい比較 | AssertJのassertThat | JUnit5標準ではないため別途導入 |
以前、前任者が退職してドキュメントがほぼ無い状態でシステムを引き継いだことがあります。
仕様書代わりになったのはテストコードで、assertの中身を読むだけで「このメソッドは何を保証すべきか」が分かりました。
半年かけてシステムを把握できたのは、テストが仕様書として機能していたからだと今でも思います。
- 迷ったらまずassertEqualsとassertThrowsを押さえれば、実務のテストコードの大半はカバーできます
- assertTrueに頼りすぎず、目的に合った専用メソッドを選ぶとエラーメッセージが読みやすくなります
- 複数条件を一度に検証したいときはassertAll、メソッドチェーンで書きたいときはAssertJを検討しましょう
私自身、最初はassertメソッドの多さに面食らいましたが、役割ごとに整理してしまえば意外とシンプルです。
この記事を辞書代わりに、目の前のテストに合ったassertを選んでみてください。