結論から言うと、JUnitのassertメソッドは目的で使い分けます。
- 値の比較:assertEquals
- 真偽値やnullの判定:assertTrue / assertNull
- 例外の検証:assertThrows
- 複数条件をまとめて検証したいとき:assertAll
迷ったらまずassertEqualsとassertThrowsを押さえれば、実務のテストコードの大半はカバーできます。
テスト対象のクラスがDBや外部APIを呼んでいて assert までたどり着けないときは、依存をモックに差し替えます。やり方はMockitoの使い方にまとめました。
JUnitでテストを書いていて、assertEqualsとassertThat、結局どっちを使えばいいんだろう…って迷ったことありませんか?私も駆け出しのころは、ネットのサンプルコードを見るたびに違うメソッドが出てきて、正直「もうassertTrueで全部済ませちゃえ」と投げやりになった時期があります。
ただ、そのやり方だとテストが失敗したときにエラーメッセージが不親切で、原因を探すのに毎回時間を溶かしていました。
この記事では、JUnit5・6の主要なassertメソッドを役割ごとに整理しました。assertThatがJUnit5に見当たらない理由とAssertJでの代替、失敗時のエラーの読み方まで、コード例つきで確認できます。全メソッドの早見表はこのすぐ下です。
この記事でわかること
- 値の一致比較(assertEquals)と配列比較(assertArrayEquals)の使い分け
- 真偽値・nullの判定に使うassertメソッド
- 例外の検証(assertThrows)とAssertJへの乗り換え方
- 複数条件をまとめて検証するassertAllの使い方
- assertが失敗したときのエラーの読み方と対処法
PARTS LIST /目次
JUnit assertメソッド早見表(目的別一覧)
目的から使うメソッドを引けるように、主なassertメソッドを一覧にしました。詳しい使い方は各セクションで解説します。
JUnitのassertとは?アサーションの基本
JUnitのassertとは、テストコード内で期待した値と実際の値が一致するかを検証する仕組みのことです。
この検証を「アサーション」と呼び、一致しなければテストは自動的に失敗します。
手動でif文を書いて確認するより圧倒的に少ないコード量で、しかも失敗理由まで出力してくれるのが強みです。
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クラスに定義されています。
書き方に破壊的変更はありません。
ただしJUnit6を使うにはJava 17以上が必要です。Java 8や11のプロジェクトはJUnit5系にとどまります。
値の比較にはどのassertメソッドを使う?
値の一致・不一致を検証したいとき、まず候補に挙がるのがこのグループです。プリミティブ型からオブジェクト、配列まで幅広くカバーしています。
assertEqualsで期待値と実際値を比較する
assertEqualsは期待値と実際値が等しいかを検証する、JUnitの中でもっとも使用頻度の高いメソッドです。
数値・文字列・オブジェクトなど幅広い型に対応しています。
@Test
void 合計金額が正しく計算されること() {
int actual = calculateTotal(1200, 3);
assertEquals(3600, actual, "合計金額の計算結果が一致しません");
}
第3引数のメッセージは省略可能ですが、私は基本的に入れる派です。
テストが数百件になってくると、メッセージなしでは「どのassertEqualsが落ちたのか」を探すだけで時間を食うようになります。
assertEqualsでdouble・floatを比較する
double・floatは計算の丸め誤差が出るため、値が同じに見えてもassertEqualsで失敗することがあります。
許容誤差(delta)を第3引数に渡すオーバーロードを使えば、その範囲内なら一致とみなされます。
assertEquals(0.3, 0.1 + 0.2, 0.0001);
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に頼ると、失敗時のメッセージがexpected: <true> but was: <false>としか出ず、原因が分かりにくくなります。可能ならassertEqualsなど専用メソッドを優先しましょう。
同じ検証をassertEqualsで書くと、失敗時に実際の値まで表示されます。
// assertTrueで書いた場合
assertTrue(users.size() == 3);
// 失敗時: expected: <true> but was: <false>
// assertEqualsで書いた場合
assertEquals(3, users.size());
// 失敗時: expected: <3> but was: <2>
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()を書いていた頃と比べると、圧倒的にすっきり書けます。
assertThrowsExactlyでサブクラスを除外して検証する
assertThrowsは、指定した例外のサブクラスが発生した場合も成功とみなします。
例外クラスそのものであることを厳密に検証したいときは、assertThrowsExactlyを使います。サブクラスが投げられるとテストは失敗します。
assertThrowsExactly(IllegalArgumentException.class, () -> order.reserve(-1));
assertDoesNotThrowで例外なしを確認する
逆に「例外が発生しないこと」を明示的にテストしたい場合はassertDoesNotThrowを使います。
リファクタリング後に想定外の例外が混ざっていないかを確認するのに向いています。
assertDoesNotThrow(() -> order.reserve(1));
assertThat非推奨とAssertJの代替
「assertThatで検索したのにJUnit5では見つからない」と混乱した経験がある人は多いはずです。
結論から言うと、JUnit5の標準にassertThatは含まれておらず、使いたい場合はAssertJへの乗り換えが基本の選択肢です。
JUnit5でassertThatが使えない理由
JUnit4のassertThatはHamcrestライブラリのMatcherに依存したメソッドでした。
JUnit4でもAssert.assertThatは4.13で非推奨になっており、JUnit5のAssertionsクラスには引き継がれませんでした。
使いたい場合は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で一括検証するメリット
1回のテスト実行で複数の不具合箇所が分かるので、修正のたびに何度もテストを回す手間が減ります。
@Test
void ユーザー情報が正しく登録されること() {
User user = userService.findById(1);
assertAll("user",
() -> assertEquals("山田太郎", user.getName()),
() -> assertEquals("[email protected]", user.getEmail()),
() -> assertTrue(user.isActive())
);
}
エラーメッセージを分かりやすくするコツ
assertAllの第1引数にはグループ名を渡せます。
ここにテスト対象の文脈が分かる文字列を入れておくと、CIのログを見ただけで「どの機能で落ちたか」が一目で分かるようになります。
地味ですが、チーム開発では効いてくる工夫です。
assertが失敗したときによくあるエラーと対処法
使い分けを押さえても、実際にテストを書き始めると、今度は失敗したときのエラーメッセージの読み方でつまずくことが多いはずです。
expected: <...> but was: <...>という表示を見て、どちらが期待値でどちらが実際の値なのか一瞬迷った経験は誰にでもあります。
結論としてはexpectedが本来こうあってほしい値、was(またはactual)がコードの実行結果です。
ここを取り違えたまま原因を追うと、直すべきコードとテストコードを逆に修正してしまうことがあるので注意してください。
org.opentest4j.AssertionFailedError:
expected: <3600> but was: <3500>
NullPointerExceptionでテストが落ちるケースも頻出です。
比較対象のオブジェクトがnullのまま、user.getName()のようにメソッドを呼んで引数を作ってしまうと、assertEqualsに値を渡す前の時点で例外が発生します。
この場合は先にassertNotNullで対象がnullでないことを確認してから、本来検証したい値をassertEqualsで比較する2段構えにすると、失敗の原因を「nullだったのか」「値が違ったのか」で切り分けられます。
「値は同じはずなのになぜか失敗する」というケースもあります。
doubleやfloatの計算結果を比べているなら、前述の許容誤差(delta)を指定するオーバーロードを使うと解決します。
オブジェクト同士の比較で常に失敗する場合は、比較対象のクラスにequals()が実装されているか(あるいは全フィールドを正しく比較できているか)を疑ってみてください。
IDEでテストを実行している場合は、失敗したテストの詳細画面に「Expected」と「Actual」を並べた差分表示が出ます。
まずはそこで期待値と実際値のどちらがおかしいかを確認してください。
次に、どのassertメソッドがどの引数の順番で呼ばれているかをコードで確認しましょう。この順番で追うと迷いにくくなります。
その他によく使うassertメソッド
ここまでで紹介しきれなかったものの、実務で意外と出番があるassertメソッドを補足しておきます。
assertSameで参照の同一性を確認する
assertEqualsが「値が等しいか」を見るのに対し、assertSameは「同一インスタンスかどうか」を検証します。
シングルトンやキャッシュされたオブジェクトが使い回されているかを確認したいときに向いています。逆に、別インスタンスであることを確かめたいときはassertNotSameを使います。
User instance1 = UserCache.get(1);
User instance2 = UserCache.get(1);
assertSame(instance1, instance2);
assertTimeoutで処理時間を検証する
処理が想定時間内に終わることを保証したいときに使います。
assertTimeoutPreemptivelyは制限時間を超えると実行を中断してテストを失敗にするため、終わらない処理の検知にも使えます。ただしテスト対象は別スレッドで実行されるので、ThreadLocalやトランザクションに依存するテストでは注意が必要です。
パフォーマンス劣化を早期に発見する目的で組み込むと安心です。
assertTimeout(Duration.ofMillis(200), () -> heavyCalculation());
assertTimeoutPreemptively(Duration.ofMillis(200), () -> heavyCalculation());
assertIterableEqualsでListの中身を比較する
assertArrayEqualsはあくまで配列用で、Listには使えません。
ListやSetなどIterableを実装したコレクションは、assertIterableEqualsで要素を先頭から順に比較します。
List<String> expected = List.of("山田", "佐藤");
List<String> actual = userService.findNames();
assertIterableEquals(expected, actual);
assertInstanceOfで型を検証する
返ってきたオブジェクトが期待する型かを確認するメソッドです。
検証に成功すると指定した型にキャスト済みの値が返るため、そのままサブクラス固有のメソッドを呼んで続きの検証ができます。
Object result = factory.create("card");
CardPayment payment = assertInstanceOf(CardPayment.class, result);
assertEquals("VISA", payment.getBrand());
fail()でテストを意図的に失敗させる
未実装のテストケースに仮置きしたり、到達すべきでない分岐に処理が来たことを検知したりする用途で使います。
TODOコメントだけ書いて放置するより、fail()を仕込んでおけば実行時に気づける分だけ安全です。
@Test
void 未実装のテスト() {
fail("まだ実装していません");
}
よくある質問(FAQ)
Q1. assertEqualsとassertThatはどちらを使うべきですか?
A1. JUnit5では標準にassertThatが含まれないため、基本はassertEqualsで十分です。複数条件をまとめて読みやすく書きたい場合は、AssertJのassertThatを別途導入するのがおすすめです。
Q2. assertThrowsで例外のメッセージまで検証できますか?
A2. できます。assertThrowsの戻り値として例外オブジェクトを受け取れるので、getMessage()の値をassertEqualsで確認すれば大丈夫です。
Q3. assertTrueばかり使うのはよくないですか?
A3. 動作はしますが、失敗時のメッセージが分かりにくくなるためおすすめしません。可能な限りassertEqualsやassertNullなど、目的に合った専用メソッドを選びましょう。
Q4. JUnit4のassertとJUnit5のassertは混在できますか?
A4. 技術的には両方のライブラリを依存に含めれば動きますが、引数の順番が異なるため事故のもとです。プロジェクト内ではどちらか一方に統一することを強くおすすめします。
Q5. assertAllを使うと処理速度は遅くなりますか?
A5. 体感できるほどの差はありません。それより一度の実行で複数の不具合を発見できるメリットのほうが、開発効率の面で大きいです。
Q6. 配列ではなくListを比較したいときは何を使いますか?
A6. assertIterableEqualsを使います。ListなどIterableを実装したコレクション同士を、要素の中身で先頭から順に比較できます。並び順が違うと失敗するため、順序が保証されないSetの比較には向きません。
Q7. assertThrowsとassertThrowsExactlyは何が違いますか?
A7. assertThrowsは指定した例外のサブクラスが発生しても成功します。assertThrowsExactlyは指定したクラスそのものが発生した場合だけ成功し、サブクラスだと失敗します。
Q8. double・floatをassertEqualsで比べると失敗するのはなぜですか?
A8. 丸め誤差により、見た目が同じ値でも内部の値がわずかにずれるためです。許容誤差(delta)を第3引数に渡すオーバーロードを使えば解決できます。
まとめ|assertメソッドの使い分け
以前、前任者が退職してドキュメントがほぼ無い状態でシステムを引き継いだことがあります。
仕様書代わりになったのはテストコードで、assertの中身を読むだけで「このメソッドは何を保証すべきか」が分かりました。
半年かけてシステムを把握できたのは、テストが仕様書として機能していたからだと今でも思います。
- 迷ったらまずassertEqualsとassertThrowsを押さえれば、実務のテストコードの大半はカバーできます
- assertTrueに頼りすぎず、目的に合った専用メソッドを選ぶとエラーメッセージが読みやすくなります
- 複数条件を一度に検証したいときはassertAll、メソッドチェーンで書きたいときはAssertJを検討しましょう
私自身、最初はassertメソッドの多さに面食らいましたが、役割ごとに整理してしまえば意外とシンプルです。
この記事を辞書代わりに、目の前のテストに合ったassertを選んでみてください。
| REV. | DATE | 内容 |
|---|---|---|
| 5 | 2026-10-21 | 一部の体験談を一般的な説明に改め、同じ説明の繰り返しを減らした |
| 4 | 2026-10-15 | 図解を描き直し(図面のデザインにそろえた) |
| 3 | 2026-09-20 | 2026年9月時点の情報で全体を見直し |
| 2 | 2026-08-21 | 2026年8月時点の情報で全体を見直し(古い記述を1件更新) |
| 1 | 2026-07-26 | 初版 |





