我正在使用 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不允许在非静态内部类中使用静态方法。如果我声明类 Cost static
那么它不会被 JUnit 收集。
我应该怎么做才能解决这个问题?
@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)
);
}
}
}
使用此模式时,每个测试类都会创建一个新的测试实例。
参数提供者
或者您可以从
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
基于 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);
}
}
}
这个游戏有点晚了,但是...
您可以在外部类中将提供程序作为静态实现。然后,在 @MethodSource 中,您只需提供参数的完全限定名称(即 com.biz.pckg#colors)。
这记录在 JUnit 用户指南中。
这是 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"
)
}
}