Javaの単体テストで状態変化を確認するには?戻り値だけでは分からない処理のテスト

最終更新日

Schoo Java入門 中級 第3回 単体テストによるビジネスロジック検証

本記事は、Schooの「Java入門 中級【2026年版】」第3回「単体テストによるビジネスロジック検証」を学ぶ前後に、Javaの単体テストで状態変化をどう確認するかを整理したい方向けの記事です。

単体テストでは、メソッドの戻り値だけを確認すればよいとは限りません。オブジェクトの中にあるフィールドの値が変わる処理では、実行後の状態も確認する必要があります。

Schoo コースページ:Java入門 中級【2026年版】

戻り値の確認と状態変化の確認は違う

たとえば、ポイントを加算する addPoints メソッドを考えます。このメソッドが加算後のポイントを返す場合、戻り値を確認できます。

ただし、オブジェクト内部の points フィールドも更新されるなら、戻り値とは別に、内部状態が変わったことも確認する必要があります。

図解:戻り値と状態変化は確認しているものが違う
実行前のオブジェクト
points = 90
メソッド実行
addPoints(20)
戻り値
return 110
オブジェクト内部の状態
points = 110
メソッドの戻り値を確認するテストと、オブジェクト内部の値が変わったことを確認するテストは、似ていますが見ている対象が違います。

テスト対象のコード例

次の PointAccount は、現在のポイントを持つクラスです。ポイントを加算すると、加算後のポイント数を返し、内部の points も更新します。

class PointAccount {
    private int points;

    PointAccount(int points) {
        if (points < 0 || points > 300) {
            throw new IllegalArgumentException("ポイントは0以上300以下で指定してください。");
        }
        this.points = points;
    }

    int getPoints() {
        return points;
    }

    int addPoints(int add) {
        if (add <= 0) {
            throw new IllegalArgumentException("加算ポイントは1以上で指定してください。");
        }

        points = points + add;

        if (points > 300) {
            points = 300;
        }

        return points;
    }
}

戻り値を確認するテスト

まず、addPoints の戻り値を確認するテストです。

@Test
void testAddPointsReturnsUpdatedPoints() {
    PointAccount account = new PointAccount(90);

    int actual = account.addPoints(20);

    assertEquals(110, actual);
}

このテストで見ているのは、addPoints(20) が返した値です。つまり、「戻り値として110が返るか」を確認しています。

状態変化を確認するテスト

次に、メソッド実行後にオブジェクト内部のポイントが更新されているかを確認します。

@Test
void testAddPointsChangesInternalState() {
    PointAccount account = new PointAccount(90);

    account.addPoints(20);

    assertEquals(110, account.getPoints());
}

このテストで見ているのは、account オブジェクトの中に残っている points の値です。戻り値を使っていない点に注目してください。

図解:何を確認するテストなのかを分ける
戻り値の確認
assertEquals(110, actual)
メソッドが返した値を見る
状態変化の確認
assertEquals(110, account.getPoints())
オブジェクト内部の値を見る
例外の確認
assertThrows(…)
受け付けない値を止められるかを見る
1つのメソッドでも、戻り値、状態変化、例外のどれを確認しているのかを分けると、テストの目的がはっきりします。

上限がある処理も状態で確認する

PointAccount では、ポイントの上限を300にしています。初期値が290のときに20ポイント加算すると、単純計算では310ですが、実際には300で止まる必要があります。

図解:上限300で止まる処理を確認する
実行前
points = 290
+
加算
addPoints(20)
=
単純計算
310
実際の結果
300
上限がある処理では、普通に加算できるケースだけでなく、上限を超えたときに期待どおり丸められるかも確認します。
@Test
void testAddPointsStopsAt300WhenResultExceedsLimit() {
    PointAccount account = new PointAccount(290);

    int actual = account.addPoints(20);

    assertEquals(300, actual);
    assertEquals(300, account.getPoints());
}

このテストでは、戻り値と状態変化の両方を確認しています。上限処理のように重要な業務ルールがある場合は、返ってきた値だけでなく、オブジェクト内部の状態も期待どおりかを見ておくと安心です。

不正な値は例外で確認する

加算ポイントが0以下の場合は、処理を進めずに例外を出す設計にしています。このような入力は assertThrows で確認します。

@Test
void testAddPointsThrowsExceptionWhenAddIsZero() {
    PointAccount account = new PointAccount(90);

    IllegalArgumentException exception = assertThrows(
            IllegalArgumentException.class,
            () -> account.addPoints(0)
    );

    assertEquals("加算ポイントは1以上で指定してください。", exception.getMessage());
}

例外のテストでは、「例外が出ること」だけでなく、必要に応じてメッセージも確認できます。

確認問題

次の仕様を持つ Wallet クラスを考えます。どのようなテストケースを作るとよいか考えてください。

charge(int amount) は残高に金額を加算し、加算後の残高を返す。残高の上限は50000円とする。加算金額が0以下の場合は例外とする。

演習後の確認:こちらのページを使って、自分で考えた内容を見直せます。

まとめ

  • 戻り値の確認と状態変化の確認は別の観点
  • フィールドの値が変わる処理では、実行後の状態も確認する
  • 上限や下限がある処理では、普通の値だけでなく上限に達するケースも確認する
  • 不正な値は assertThrows で確認する

関連する記事

シェアする