JUnit5 チートシート（アサーション編）

本記事はこちらのユーザーガイド及び情報サイトを参考に投稿しています。

https://oohira.github.io/junit5-doc-jp/user-guide/#overview
http://www.ne.jp/asahi/hishidama/home/tech/java/junit/5/assertion.html#h_assertSame

関連記事はこちら
https://qiita.com/shinjimorimoto/items/e1760f92b8bf67409710

----

# 概要
以下で紹介するメソッドはAssertionsクラスのstaticメソッドとして定義されている。
また、JUnit5では検証失敗時のメッセージをAssertメソッドの __最後の引数__ に指定する。

# fail()
テストを失敗させる検証
※テスト駆動開発はまずこのテストから始まる
```java
	@Test
	void failure1() {
		fail("テスト失敗");
	}
```

# assertTrue(condition)
condition（boolean）が真であることを検証する
```java
    @Test
    void trueAssertion() {
        assertTrue("abc".length() > 1);
    }
```

# assertFalse(condition)
condition（boolean）が偽であることを検証する
```java
    @Test
    void falseAssertion() {
        assertFalse("abc".length() < 1);
    }
```

# assertNull(actual)
nullであることを検証する
```java
	@Test
	void nullAssertion() {
		assertNull(Null);
	}
```

# assertNotNull(actual)
nullでないことを検証する
```java
	@Test
	void notNullAssertion() {
		assertNotNull("");
	}
```

# assertEquals(expected, actual)
expected(期待値) = actual(実測値) であることを検証する

```java
    @Test
    void standardAssertions() {
        assertEquals(2, 2);
    }
```

# assertNotEquals(expected, actual)
expected(期待値) ≠ actual(実測値) であることを検証する

```java
    @Test
    void standardAssertions() {
        assertNotEquals(2, 3);
    }
```

# assertThrows(例外クラス, function)
functionを実行した結果、例外クラスがThrowされることを検証する
```java
    @Test
    void testOutOfBounds() {
    	List<Object> it = new ArrayList<>();
    	assertThrows(IndexOutOfBoundsException.class, () -> it.get(1));
    }
```

# assertDoesNotThrow(function)
functionを実行した結果、例外がThrowされないことを検証する
```java
    @Test
    void testOk() {
        List<String> it = Arrays.asList("a", "b", "c");
        assertDoesNotThrow(() -> it.get(1));
    }
```

# assertTimeout(long, function)
指定時間内(long)に処理(function)が完結することを検証する

```java
    @Test
    void timeoutNotExceeded() {
        assertTimeout(Duration.ofMinutes(2), () -> {
            // ２秒以内に処理が終わったらこのアサーションは成功する。
        });
    }

    @Test
    void timeoutExceeded() {
        assertTimeout(Duration.ofMillis(10), () -> {
            // この処理は100ミリかかるので失敗する。
            Thread.sleep(100);
        });
    }
```

# assertTimeoutPreemptively(long, function)
指定時間内(long)に処理(function)が完結することを検証する
```java
    @Test
    void timeoutExceeded() {
        assertTimeout(Duration.ofMillis(10), () -> {
            // この処理は100ミリかかるので失敗する。
            Thread.sleep(100);
        });
    }
```

:::note info
__assertTimeout__
　：タイムアウトした場合でもfunctionの実行完了を待ってエラーを出力する
__assertTimeoutPreemptively__
　：タイムアウトした場合は直ちにfunctionの実行を終了し、エラーを出力する
:::

# assertArrayEquals(expected, actual)
expected(期待値の配列) = actual(実測値の配列) であることを検証する
```java
	@Test
	void array() {
		int[] expected = { 1, 2, 3 };
		int[] actual   = { 1, 2, 3 };
		assertArrayEquals(expected, actual);
	}
```

# assertIterableEquals(expected, actual)
expected(期待値の配列) = actual(実測値の配列) であることを検証する
```java
	@Test
	void iterable() {
		List<String> expected = Arrays.asList("a", "b", "c");
		List<String> actual   = Arrays.asList("a", "b", "c");
		assertIterableEquals(expected, actual);
	}
```

:::note info
__assertEquals__ でも比較することができるが、検証失敗の場合に不一致の要素が表示されない
__assertIterableEquals__ を使用すれば不一致の要素が出力される
:::

# assertLinesMatch(expected, actual);
複数行にわたるメッセージ（スタックトレースとかログメッセージ）の比較にはassertLinesMatchが便利。
assertLinesMatchは、基本的にはList<String>の比較。
だが、期待値の方に正規表現等を指定できる。
```java
	@Test
	void linesMatch() {
		List<String> expected = Arrays.asList("\\d+ms", "abc", ">> skip >>", ".{3}");
		List<String> actual   = Arrays.asList("123ms", "abc", "1", "2", "3", "zzz");
		assertLinesMatch(expected, actual);
	}
```
「\\d+ms」や「.{3}」は正規表現。

「>> >>」は、次のデータがマッチするまでスキップする。「>> コメント >>」のように間に文字列を書いた場合はコメント扱いで無視されるが、
「>> 3 >>」のように数値を書いた場合はその行数分スキップする。


# assertSame(expected, actual)
expected(期待値のインスタンス) = actual(実測値のインスタンス) であることを検証する
```java
    @Test
    void sameAssertion() {
        List<String> expected = new ArrayList<>();
        List<String> actual = expected;
        assertSame(expected, actual);
    }
```

# assertNotSame(expected, actual)
expected(期待値のインスタンス) ≠ actual(実測値のインスタンス) であることを検証する
```java
    @Test
    void notSameAssertion() {
        List<String> expected = new ArrayList<>();
        List<String> actual = new ArrayList<>(expected);
        assertNotSame(expected, actual);
    }
```
:::note info
__assertSame__ , __assertNotSame__ はプリミティブ型（int, long, boolean等）であればassertEqualsと何ら変わりありません。
:::

# assertAll(任意のグループ名, function・・・)
アサーションをグループ化することですべてのアサーションが一度に実行され、すべての失敗がまとめて検証される

```java
    @Test
    void groupedAssertions() {
        T001Form form = new T001Form("1", "2");
        assertAll("任意のグループ名（テスト失敗時に出力されます）",
                () -> assertEquals("1", form.getText1()),
                () -> assertEquals("2", form.getText2())
        );
    }
```

下記のように階層構造にすることも可能
```java
    @Test
    void dependentAssertions() {
        // コードブロック内でアサーションが失敗すると、同じブロック内の後続のコードはスキップされる。
        assertAll("properties",
            () -> {
                String firstName = person.getFirstName();
                assertNotNull(firstName);

                // 上のアサーションが成功した場合のみ実行される。
                assertAll("first name",
                    () -> assertTrue(firstName.startsWith("J")),
                    () -> assertTrue(firstName.endsWith("n"))
                );
            },
            () -> {
                // グループ化されたアサーションは、first name のアサーションとは独立して実行される。
                String lastName = person.getLastName();
                assertNotNull(lastName);

                // 上のアサーションが成功した場合のみ実行される。
                assertAll("last name",
                    () -> assertTrue(lastName.startsWith("D")),
                    () -> assertTrue(lastName.endsWith("e"))
                );
            }
        );
    }
```