JUnit テストの記述方法

# はじめに
JUnit その3です。今回から実際にJUnitの内容に入っていきたいと思います。
まずは、JUnit5でのテストコードの記述方法についてです。
不備等あるかもしれませんがご了承ください。

# JUnitシリーズ 項目表
| NO 　　　　| タイトル               |
| ---- | ------------------- |
| その1 | [JUnit 単体テストの概要](https://qiita.com/ryo0527/items/70550e0a556975a593f5) |
| その2 | [JUnit 環境の準備](https://qiita.com/ryo0527/items/135c2104a9af0eb795e9)　|
| その3 | [JUnit テストの記述方法](https://qiita.com/ryo0527/items/7e85b3444fa9c975eecb) |

JUnit5を動かす環境の準備は、その2でおこなっています。

単体テストの概要については、その1に記載しております。
気になる方は、是非ご覧ください。

※ 新しい記事が作成できましたら、表は更新します。

# テストクラスの作成
テストコードは、下記のように`test`配下にテストクラスを作成し実装します。
```
├─demo
│  └─src
│      └─test
│          └─java
│              └─com
│                  └─example
```

例） `Sample`クラスに対するテストコードを記述する場合
```
├─test
│  └─src
│      ├─main
│      │  └─java
│      │      └─com
│      │          └─example
│      │                Sample.java
│      │
│      └─test
│         └─java
│             └─com
│                 └─example
│                       SampleTest.java
```
上記のようにテストクラスは、基本的にテスト対象のクラスと同じ階層に作成します。

# アノテーション
テストコードで使用するアノテーションの一部を紹介します。
今回紹介するアノテーション以外にもJUnit5ではたくさんのアノテーションが提供されています。

| アノテーション    | 説明                          |
| ------------- | ---------------------------- |
| `@Test`       | テストメソッドであることを示す。<br />単一のテストが実行される。 |
| `@BeforeAll`  | テストクラスのすべてのテストメソッドの実行前に一度だけ実行される。|
| `@BeforeEach` | テストクラスの各テストメソッドの実行前に毎回実行される。|
| `@AfterAll` | テストクラスのすべてのテストメソッドの実行後に一度だけ実行される。|
| `@AfterEach`  | テストクラスの各テストメソッドの実行後に毎回実行される。|

文章だけだと、イメージしにくいので実際に処理を動かしてみます。
```java:
public class SampleTest {

  @BeforeAll
  public static void initAll() {
    System.out.println("@BeforeAll");
  }

  @AfterAll
  public static void tearDownAll() {
    System.out.println("@AfterAll");
  }

  @BeforeEach
  public void init() {
    System.out.println("@BeforeEach");
  }

  @AfterEach
  public void tearDown() {
    System.out.println("@AfterEach");
  }

  @Test
  public void testSample1() {
    System.out.println("testSample1");
  }

  @Test
  public void testSample2() {
    System.out.println("testSample2");
  }
}
```

```:実行結果
@BeforeAll
@BeforeEach
testSample1
@AfterEach
@BeforeEach
testSample2
@AfterEach
@AfterAll
```
実行結果からも分かるように、最初のテストメソッドが呼び出される前に `@BeforeAll` が付与されたメソッドが実行されています。次に、各テストメソッドの前後でそれぞれ `@BeforeEach` と `@AfterEach`　が付与されたメソッドが実行されています。最後に、テストクラスの最後のテストメソッドが実行された後に `@AfterAll` が付与されたメソッドが実行されています。

テストメソッドの前後で共通して行いたい処理などはアノテーションを使用することで、簡潔に記述することができます。

# 検証メソッド
検証メソッドについて紹介します。

| 検証メソッド    　　　      | 説明                          |
| ------------------- | ---------------------------- |
| `assertEquals`      | 期待値と実行結果が等しいかを検証する。|
| `assertArrayEquals` | 期待値(配列)と実行結果が等しいかを検証する。|
| `assertTrue` 　　　　　　　　　　　　　　| 期待値がtrueかを検証する。|
| `assertFalse`　　　　　　　　　　　　 | 期待値がfalseかを検証する。|
| `assertNull`  　　　　　　　　　　　　| 期待値がnullかを検証する。|
| `assertNotNull`     | 期待値がnullでないかを検証する。|
| `assertSame`        | 期待値と実行結果が同じインスタンスかを検証する。|
| `fail`              | テストを失敗させる。<br />開発が完了していないときにテストをマークするのに使用したりする。 |
| `assertIterableEquals` | 期待値(リストなど)と実行結果が等しいかを検証する。<br />不一致だった場合、「不一致だった要素」が表示される。|
| `assertAll`         | すべてのアサーションが実行され、それらの失敗がまとめて報告される。|
| `assertThrows`      | 例外が発生するかを検証する。　|
| `assertTimeout`     | タイムアウトしない（一定時間内に終了すること）かを検証する。|

文章だけだと、イメージしにくいので、実際に`assertEquals`メソッドの処理を動かしてみます。

- テスト対象クラス
```java:Sample.java
public class Sample {
  public static String getValue() {
    return "Sample";
  }
}
```

- テストクラス
```java:SampleTest.java
public class SampleTest {
  @Test
  public void testGetValue() {
    assertEquals("Sample", Sample.getValue());
  }
}
```
検証メソッドについては、下記記事が非常に分かりやすかったです。
- [JUnit5 テストの記述](http://www.ne.jp/asahi/hishidama/home/tech/java/junit/5/assertion.html#h_assertThrows)

### assertThat
他の検証メソッドと違い、assertThatメソッドだけ特殊なため、例を用いて説明していきます。

#### assertThatとは
今まで紹介したメソッドでは、比較するものによってメソッドを使い分けていたが、
assertThatでは、引数で何を比較するかを指定することができる。

#### assertThatメリット
assertThatを使うメリットとして、下記のようなことが挙げられます。
- コードの可読性が高くなる
- エラーメッセージが分かりいやすい

#### 依存関係の追加
assertThatを使用するために、依存関係を追加する必要があります。
pomファイルに下記を追加します。

```xml:pom.xml
<dependencies>
  <dependency>
    <groupId>org.assertj</groupId>
    <artifactId>assertj-core</artifactId>
    <version>3.19.0</version>
    <scope>test</scope>
  </dependency>
</dependencies>
```
#### assertThatの例
```java
// assertEqualsの場合;
assertEquals(3, 1 + 2);

// assertThatの場合;
assertThat(1 + 2).isEqualTo(3);
```
assertThatについては、下記記事が非常に分かりやすかったです。
- [AssertJ版：テストでよく使う検証メソッド一覧](https://qiita.com/naotawool/items/6512ecbe2fd006dacfd2)

# おわりに
JUnit5での基本的なテスト記述方法については、以上になります。
間違っている箇所ありましたら、ご指摘いただければ幸いです。
紹介できていない記述方法については、時間のある際に更新していきたいと思います。