[JUnit 5]@MethodSourceに非staticメソッドを指定するには

技術情報

パラメーター化テストを使おうとして少しハマった件。

        @Nested
        class DoubleTest {

            @ParameterizedTest
            @MethodSource("prepArguments")
            void testDouble(int x, int expected) {
                int y = x * 2;
                assertThat(y, is(expected));
            }

            Stream<Arguments> prepArguments() {
                return Stream.of(
                        arguments(1, 2),
                        arguments(2, 4)
                );
            }
        }

以下の例外が発生。

org.junit.platform.commons.PreconditionViolationException: Cannot invoke non-static method [java.util.stream.Stream<org.junit.jupiter.params.provider.Arguments> com.example.PersonSelfDocumentingTest$GetKazoedoshi$DoubleTest.prepArguments()] on a null target.

通常はstaticメソッドしか使用できないらしい。が、ユーザーガイドに以下の記述あり。

“per-class(クラス毎)” モードは、デフォルトの “per-method(メソッド毎)” モードに比べて 追加のメリットがあります。具体的には、”per-class” モードでは @BeforeAll および @AfterAll をインターフェースの default メソッドやクラスの非staticなメソッドに 対して宣言できるようになります。そのため、”per-class” モードでは @BeforeAll や @AfterAll メソッドを @Nested テストクラスでも使えます。

というわけでテストクラスに @TestInstance(TestInstance.Lifecycle.PER_CLASS) を付与することで解決。

        @TestInstance(TestInstance.Lifecycle.PER_CLASS)
        @Nested
        class DoubleTest {

            @ParameterizedTest
            @MethodSource("prepArguments")
            void testDouble(int x, int expected) {
                int y = x * 2;
                assertThat(y, is(expected));
            }

            Stream<Arguments> prepArguments() {
                return Stream.of(
                        arguments(1, 2),
                        arguments(2, 4)
                );
            }
        }

コメント

タイトルとURLをコピーしました