Java

例外処理とテスト

失敗の原因を読み、想定内の失敗へ対応し、結果を自動で確認しましょう。

01

スタックトレースを読む

例外が起きたら、先頭の例外名と説明を読み、at クラス名.メソッド名(ファイル名:行番号)から自分のコードを探します。

失敗するコードJAVA
int[] scores = {80, 90};
System.out.println(scores[2]);
表示例OUTPUT
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
Index 2 out of bounds for length 2

長さ2の配列で使える添字は0と1です。この場合はscores[1]へ直します。

02

想定できる失敗を処理する

数値変換の失敗だけを捕まえ、利用者へ再入力を促せるメッセージを表示します。

try-catchJAVA
String input = "abc";
try {
    int number = Integer.parseInt(input);
    System.out.println(number * 2);
} catch (NumberFormatException e) {
    System.out.println("整数を入力してください");
} finally {
    System.out.println("処理を終了します");
}
実行結果OUTPUT
整数を入力してください
処理を終了します

finallyは成功・失敗にかかわらず実行されます。閉じる必要があるリソースには、原則としてtry-with-resourcesを使います。

03

不正な値を知らせる

メソッドが受け付けられない値にはIllegalArgumentExceptionを投げ、呼び出し側へ原因を伝えます。

割引計算JAVA
static int discount(int price, int percent) {
    if (price < 0) {
        throw new IllegalArgumentException("価格は0以上にしてください");
    }
    if (percent < 0 || percent > 100) {
        throw new IllegalArgumentException("割引率は0〜100です");
    }
    return price * (100 - percent) / 100;
}

System.out.println(discount(2000, 20));
実行結果OUTPUT
1600
04

JUnit 5で自動テストする

Mavenプロジェクトのsrc/test/javaへテストを置きます。通常値と境界値、失敗する値を確認します。

PriceTest.javaJAVA
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;

class PriceTest {
    @Test
    void 二割引を計算できる() {
        assertEquals(1600, Price.discount(2000, 20));
    }

    @Test
    void 範囲外の割引率は失敗する() {
        assertThrows(IllegalArgumentException.class,
            () -> Price.discount(2000, 101));
    }
}
実行COMMAND
mvn test
成功時の要点OUTPUT
Tests run: 2, Failures: 0, Errors: 0
BUILD SUCCESS

依存関係とMavenの設定はビルドと依存関係で扱います。

PRACTICE

ミニ課題:送料計算のテスト

注文金額が5000円以上なら送料無料、それ未満なら500円を返すメソッドを作ります。0円、4999円、5000円、負の金額をテストし、負なら例外にしてください。