JUnit5 チートシート（アノテーション編）

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

https://oohira.github.io/junit5-doc-jp/user-guide/#overview

----

# <span>@</span>Test
このメソッドが、テストメソッドであることを示します。
```java
@Test
void test() {
    assertEquals(2, 1 + 1);
}
```

# <span>@</span>ParameterizedTest
このメソッドが、パラメーター化テスト であることを示します。
```java
@ParameterizedTest
@ValueSource(strings = { "soccer", "tennis", "baseball" })
void parameter1(String params) {
    assertTrue(params.contains("e"));
}
```
* ValueSourceで指定された値が１つずつ評価され、NGが検出されても全量テストされます。

```java
@ParameterizedTest
@CsvSource({
        "12345, 0",
        "1234, 1"
})
void parameter2(ArgumentsAccessor arguments) {
    assertTrue(arguments.getString(0).length() <= 5);
    assertTrue(arguments.getString(1).length() <= 1);
}
```
* CsvSourceで指定された値が１行ずつ評価され、NGが検出されても全量テストされます。

# <span>@</span>RepeatedTest
このメソッドが、繰り返しテスト のためのテストテンプレートであることを示します。
```java
@RepeatedTest(5)
void repeated() {
    Random rand = new Random();
    int num = rand.nextInt(10);
    assertTrue(num < 10);
}
```
* 括弧内の回数分テストが実行され、１度でもNGの場合はNGと評価されます。

# <span>@</span>TestFactory
このメソッドが、動的テストのためのテストファクトリであることを示します。
　⇒　複数のアサーションをまとめたい場合に適用するもの

```java
@TestFactory
List<DynamicTest> dynamicTest1() {
    List<DynamicTest> list = new ArrayList<>();
    list.add(dynamicTest("test1", () -> assertEquals(2, 2 + 1)));
    System.out.println("test1 end");
    list.add(dynamicTest("test2", () -> assertEquals(2, 1 + 1)));
    System.out.println("test2 end");
    return list;
}
```
* 基本的にはアサーションは１つが良いとされているが、複数のアサーションをまとめたい場合に適用する
* TestFactoryを使わずにアサーションを複数指定した場合、NGとなった以降の処理は実行されないが、上記の場合は全て実行される。（プリント処理はその確認用）


# <span>@</span>TestInstance
クラスに対して指定します。
アノテーションを付与したテストクラスに対して、テストインスタンスのライフサイクル を設定するために使われます。
```java
// PER_CLASSを指定
@TestInstance(PER_CLASS) // ・・・ テストクラス単位でインスタンスを生成
//@TestInstance(PER_METHOD) ・・・ （デフォルト）メソッド単位でインスタンス生成
class SampleTest {

    @Test
    void test() {
        assertEquals(2, 1 + 1);
    }

    @ParameterizedTest
    @ValueSource(strings = {"soccer", "tennis", "baseball"})
    void parameter1(String params) {
        assertTrue(params.contains("i"));
    }
}
```

# <span>@</span>DisplayName
テストクラスやテストメソッドにカスタムの表示名を指定します。
表示名は実行結果に反映されます。
```java
@Test
@DisplayName("サンプルテスト")
void test() {
    assertEquals(2, 1 + 1);
}
```
# <span>@</span>BeforeEach　<span>@</span>AfterEach

このメソッドが、現在のクラスの @Test, @RepeatedTest, @ParameterizedTest, @TestFactory メソッドの 前（後）に毎回 実行されるよう指定します。JUnit 4の @Before と同じです。

```java
@BeforeEach
void beforeEach() {
    // 各テストメソッド実行前に実行される
}

@AfterEach
void afterEach() {
    // 各テストメソッド実行後に実行される
}
```
# <span>@</span>BeforeAll　<span>@</span>AfterAll
このメソッドが、現在のクラスの すべての @Test, @RepeatedTest, @ParameterizedTest, @TestFactory メソッドの 前（後）に一度だけ 実行されるよう指定します。JUnit 4の @BeforeClass と同じです。 このメソッドは、（隠す か オーバーライドする かしない限り）継承 されますが、（テストインスタンスのライフサイクル に "per-class" が使われない限り）static でなければいけません。

```java
@BeforeAll
void beforeAll() {
    // 現在のクラスの実行前に１度だけ実行される
}

@AfterAll
void afterAll() {
    // 現在のクラスの実行後に１度だけ実行される
}
```
# <span>@</span>Nested	
このクラスが、ネストした非staticのテストクラスであることを示します。 @BeforeAll および @AfterAll メソッドは、テストインスタンスのライフサイクル に "per-class" が使われない限り、@Nested テストクラスの中で直接使うことはできません。

```java
class SampleTest {

    @Nested
    class inputCheck {
        @Test
        void test1() {
            assertEquals(2, 1 + 1);
        }
        @Test
        void test2() {
            assertEquals(2, 1 + 1);
        }
    }

    @Nested
    class outputCheck {
        @Test
        void test1() {
            assertEquals(2, 1 + 1);
        }
        @Test
        void test2() {
            assertEquals(2, 1 + 1);
        }
    }
}
```

# <span>@</span>Tag
クラスまたはメソッドレベルでテストをフィルタリングするための タグ を宣言するのに使われます。TestNGのテストグループやJUnit 4のCategoryと同じです。
```java
@Tag("tag1")
class SampleTagTest {

    @Nested
    class inputCheck {
        @Test
        @Tag("tagMethod1")
        void test1() {
            assertEquals(2, 1 + 1);
        }
        @Test
        void test2() {
            assertEquals(2, 1 + 1);
        }
    }
}
```

Tagの実行設定はbuild.gradleへ指定する
```build.gradle
test {
    useJUnitPlatform{
        includeTags 'tag1'
        excludeTags 'tagMethod1'
    }
}
```

# <span>@</span>Disabled
テストクラスやテストメソッドを 無効化 するのに使われます。JUnit4の<span>@</span>Ignoreと同じです。
```java
@Disabled
@Test
void sample() {
    assertEquals(2, 1 + 1);
}
```
# <span>@</span>ExtendWith
カスタムの 拡張機能 を登録するために使われます。
```java
@ExtendWith(SpringExtension.class)
class SampleExtendTest {

    @Autowired
    private ApplicationContext applicationContext;

    @Test
    void defaultContextTest() {
        Assertions.assertEquals(1, applicationContext.getBeansOfType(MessageSource.class).size());
    }
}
```
様々な拡張機能を利用できますが、@AutowiredでDIを実現したい場合は「SpringExtension.class」を指定します。


# <span>@</span>TestTemplate
このメソッドが、テストケースのテンプレート であることを示します。このメソッドは、登録したプロバイダが返す実行コンテキストの数に応じて、複数回呼び出されます。
登録したプロバイダが返す実行コンテキスト：MyTestTemplateInvocationContextProvider.classを指す
この場合、同プロバイダから「foo」「bar」の2つがテストクラスのparameterとして実行される。（2回実行）

```java
@TestTemplate
@ExtendWith(MyTestTemplateInvocationContextProvider.class)
void testTemplate(String parameter) {
    assertEquals(3, parameter.length());
}
```

```MyTestTemplateInvocationContextProvider.java
    @Override
    public boolean supportsTestTemplate(ExtensionContext context) {
        return true;
    }

    @Override
    public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(ExtensionContext context) {
        return Stream.of(invocationContext("foo"), invocationContext("bar"));
    }

    private TestTemplateInvocationContext invocationContext(String parameter) {
        return new TestTemplateInvocationContext() {
            @Override
            public String getDisplayName(int invocationIndex) {
                return parameter;
            }

            @Override
            public List<Extension> getAdditionalExtensions() {
                return Collections.singletonList(new ParameterResolver() {
                    @Override
                    public boolean supportsParameter(ParameterContext parameterContext,
                                                     ExtensionContext extensionContext) {
                        return parameterContext.getParameter().getType().equals(String.class);
                    }

                    @Override
                    public Object resolveParameter(ParameterContext parameterContext,
                                                   ExtensionContext extensionContext) {
                        return parameter;
                    }
                });
            }
        };
    }
```