JUnit 5 @嵌套类中的MethodSource

q5lcpyga  于 2023-10-20  发布在  其他
关注(0)|答案(4)|浏览(110)

我正在使用JUnit 5,我想在嵌套类中创建参数化测试。举例来说:

class CardTest {
    @Nested
    class Cost {
        Stream<Arguments> cards() {
            return Stream.of(
                Arguments.of(Card.common(0, Color.RED), 0),
                /** Other Data **/
                Arguments.of(Card.choseColor(), 50)
            );
        }
        @MethodSource("cards")
        @ParameterizedTest
        void cardCost(Card card, int cost) {
            assertThat(card.cost()).isEqualTo(cost);
        }
    }
    /** Some other nested classes or simple methods **/
}

问题是@MethodSource要求指定的方法必须是static。但是Java不允许在非静态内部类中使用静态方法。如果我声明类Coststatic,那么它不会被JUnit收集。
我应该怎么做来解决这个问题?

vbopmzt1

vbopmzt11#

@TestInstance(PER_CLASS)

您可以选择“每个类单个测试示例”模式,用@TestInstance(TestInstance.Lifecycle.PER_CLASS)注解嵌套类:

class ColorTest {

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

        @ParameterizedTest
        @MethodSource("colors")
        void blue(Color color, int blue) {
            Assertions.assertEquals(color.getBlue(), blue);
        }

        Stream<Arguments> colors() {
            return Stream.of(
                    Arguments.of(Color.BLACK, 0),
                    Arguments.of(Color.GRAY, 128),
                    Arguments.of(Color.BLUE, 255)
            );
        }
    }

}

使用此模式时,每个测试类将创建一个新的测试示例。

ArgumentsProvider

或者您可以从MethodSource切换到ArgumentsProvider
我修改了你的例子,看看它是否可以在本地编译和运行:

class ColorTest {

    static class Blues implements ArgumentsProvider {

        @Override
        public Stream<Arguments> provideArguments(ExtensionContext context) {
            return Stream.of(
                    Arguments.of(Color.BLACK, 0),
                    Arguments.of(Color.GRAY, 128),
                    Arguments.of(Color.BLUE, 255)
            );
        }
    }

    @Nested
    class Inner {

        @ParameterizedTest
        @ArgumentsSource(Blues.class)
        void blue(Color color, int blue) {
            Assertions.assertEquals(color.getBlue(), blue);
        }
    }

}

更多详情请访问http://junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests

p4rjhz4m

p4rjhz4m2#

另一个基于JUnit 5.2.0的变体是这样的。

class ColorTest {

public static Stream<Arguments> provideColors() {
    return Stream.of(
            Arguments.of(Color.BLACK, 0),
            Arguments.of(Color.GRAY, 128),
            Arguments.of(Color.BLUE, 255)
    );
}

@Nested
class Inner {

    @ParameterizedTest
    @MethodSource("com.domain.ColorTest#provideColors")
    void blue(Color color, int blue) {
        Assertions.assertEquals(color.getBlue(), blue);
    }
}

}

ecr0jaav

ecr0jaav3#

有点晚了,但是...
可以在外部类中将提供程序实现为静态提供程序。然后,在@MethodSource中,您只需提供参数的完全限定名(即,com.biz.pckg#colors)。
这在JUnit用户指南中有说明。

fslejnso

fslejnso4#

以下是Kotlin的解决方案:

class MyContainerTest {

    @Nested
    @TestInstance(Lifecycle.PER_CLASS)
    inner class MyNestedTest {
 
        @ParameterizedTest
        @MethodSource("generateArgs")
        fun `Test should work`(
            argument: String
        ) {
            // Use the argument
        }

        private fun generateArgs() = listOf(
            "abc",
            "xyz",
            "1234"
        )
    }
}

相关问题