JUnit 4 @Test アノテーションの expected で指定した例外が発生したとき・しなかったときの挙動を確認する

## 概要

- @Test アノテーションの expected に例外クラスを指定したテストにて、例外が発生したとき・発生しなかったときの挙動を確認する
- サンプルプログラムで挙動を確認する
- JUnit 4.12 を使用する

## @Test アノテーションの expected について

@Test アノテーションの expected は、指定した例外が投げられた際にテストを成功とする。
指定した例外が投げられなかった場合はテストが失敗する。

[Test \(JUnit API\)](https://junit.org/junit4/javadoc/4.12/org/junit/Test.html#expected())

> Optionally specify expected, a Throwable, to cause a test method to succeed if and only if an exception of the specified class is thrown by the method. If the Throwable's message or one of its properties should be verified, the ExpectedException rule can be used instead.

## サンプルプログラム

### ソースコード一覧

```
├── pom.xml
└── src
    ├── main
    │   └── java
    │       └── com
    │           └── example
    │               └── Calculator.java
    └── test
        └── java
            └── com
                └── example
                    └── CalculatorTest.java
```

### Maven のビルド用ファイル pom.xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example</groupId>
  <artifactId>test</artifactId>
  <version>1.0-SNAPSHOT</version>

  <properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <!-- https://mvnrepository.com/artifact/junit/junit -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

</project>
```

### Calculator.java

[Getting started · junit\-team/junit4 Wiki · GitHub](https://github.com/junit-team/junit4/wiki/Getting-started) で紹介されているサンプルクラスを参考にする。

```java
package com.example;

public class Calculator {
  public int evaluate(String expression) {
    int sum = 0;
    for (String summand : expression.split("\\+"))
      sum += Integer.valueOf(summand);
    return sum;
  }
}
```

### CalculatorTest.java 

Calculator クラスのテストクラス。

```java
package com.example;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class CalculatorTest {

  // "1+2+3" を指定して 6 が返ってきたらテスト成功
  @Test
  public void testEvaluate() {
    Calculator calculator = new Calculator();
    int sum = calculator.evaluate("1+2+3");
    assertEquals(6, sum);
  }

  // NullPointerException が発生したらテスト成功
  @Test(expected = NullPointerException.class)
  public void testEvaluateException() {
    Calculator calculator = new Calculator();
    int sum = calculator.evaluate(null);
  }

  // NullPointerException が発生したらテスト成功
  // (今回は発生しないのでテストは失敗する)
  @Test(expected = NullPointerException.class)
  public void testEvaluateFailed() {
    Calculator calculator = new Calculator();
    int sum = calculator.evaluate("1+2+3");
  }
}
```

## テストを実行

mvn test コマンドでテストを実行する。

```
$ mvn test
(中略)
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.example.CalculatorTest
Tests run: 3, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.116 sec <<< FAILURE!
testEvaluateFailed(com.example.CalculatorTest)  Time elapsed: 0.017 sec  <<< FAILURE!
java.lang.AssertionError: Expected exception: java.lang.NullPointerException
(中略)

Results :

Failed tests:   testEvaluateFailed(com.example.CalculatorTest): Expected exception: java.lang.NullPointerException

Tests run: 3, Failures: 1, Errors: 0, Skipped: 0
```

CalculatorTest クラスの testEvaluateFailed メソッドのテストが失敗しているのを確認できる。
「@Test(expected = NullPointerException.class)」を記述したが、NullPointerException が発生しなかったため。

## 参考資料

- [Getting started · junit\-team/junit4 Wiki · GitHub](https://github.com/junit-team/junit4/wiki/Getting-started)
- [Exception testing · junit\-team/junit4 Wiki · GitHub](https://github.com/junit-team/junit4/wiki/Exception-testing)
- [Overview \(JUnit 4.12 API\)](https://junit.org/junit4/javadoc/4.12/)
- [Annotation Type Test \(JUnit 4.12 API\)](https://junit.org/junit4/javadoc/4.12/org/junit/Test.html)