是否可以使用JUnit5的参数化新功能来运行测试类以接收测试参数,而不是在方法级别上进行?
在JUnit 4中,可以使用诸如@RunWith(Parameterized::class)
等运行器和继承来将参数数组传递给子类,但我不确定是否可以使用新的JUnit 5 API实现类似的功能。
是否可以使用JUnit5的参数化新功能来运行测试类以接收测试参数,而不是在方法级别上进行?
在JUnit 4中,可以使用诸如@RunWith(Parameterized::class)
等运行器和继承来将参数数组传递给子类,但我不确定是否可以使用新的JUnit 5 API实现类似的功能。
简短回答
使用JUnit 5无法按照JUnit 4的风格对类创建进行参数化。
幸运的是,将测试逻辑和测试输入数据(参数)分离的意图可以以不同的方式实现。
JUnit 5有自己的方法来制作参数化测试,当然,它与JUnit 4不同。新方法不允许在类级别使用参数化fixtures(即通过其每个测试方法)。
因此,每个参数化测试方法都应明确注释为链接到参数。
JUnit 5提供了许多参数源类型,可以在文档和指南中找到。
在您的情况下,从Junit 4迁移的最简单方式是使用org.junit.jupiter.params.provider.*
的@MethodSource
或@ArgumentsSource
而不是@Parameters
。
JUnit 4:
@RunWith(Parameterized.class)
public class MyTestWithJunit4 {
@Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {
{ 0, 0, 0 },
{ 1, 2, 3 },
{ 5, 3, 8 }
});
}
int first;
int second;
int sum;
public MyTestWithJunit4(int first, int second, int sum) {
this.first = first;
this.second = second;
this.sum = sum;
}
@Test
public void test() {
assertEquals(sum, first + second));
}
}
JUnit 5(使用@MethodSource
):
class MyTestWithJunit5 {
@DisplayName("Test with @MethodSource")
@ParameterizedTest(name = "{index}: ({0} + {1}) => {2})")
@MethodSource("localParameters")
void test(int first, int second, int sum) {
assertEquals(sum, first + second);
}
static Stream<Arguments> localParameters() {
return Stream.of(
Arguments.of(0, 0, 0),
Arguments.of(1, 2, 3),
Arguments.of(5, 3, 8)
);
}
}
JUnit 5(使用@ArgumentsSource
):
class MyTestWithJunit5 {
@DisplayName("Test with @ArgumentsSource")
@ParameterizedTest(name = "{index}: ({0} + {1}) => {2})")
@ArgumentsSource(Params.class)
void test(int first, int second, int sum) {
assertEquals(sum, first + second);
}
static class Params implements ArgumentsProvider {
@Override
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
return Stream.of(
Arguments.of(0, 0, 0),
Arguments.of(1, 2, 3),
Arguments.of(5, 3, 8)
);
}
}
}
@MethodSource
中的方法和@ArgumentsSource
中的类可以在任何地方描述,不仅限于测试方法所在的同一类。此外,@MethodSource
允许提供多个源方法,因为它的value
是一个String[]
。junit-jupiter-engine
中,而是位于单独的依赖项junit-jupiter-params
中。创建一个元注解来指定参数化,并将其应用于测试方法:
public class MyTest {
@ParameterizedTest(name = "{0}")
@MethodSource("allImplementations")
@Retention(RetentionPolicy.RUNTIME)
private @interface TestAllImplementations {
}
static Stream<Arguments> allImplementations() {
return Stream.of(
Arguments.of("Serial", new SerialWidget()),
Arguments.of("Concurrent", new ConcurrentWidget())
);
}
@TestAllImplementations
void myFirstTest(String name, Widget implementation) {
/* ... */
}
@TestAllImplementations
void mySecondTest(String name, Widget implementation) {
/* ... */
}
}
public class NewParametricTest {
@Nested
public class NewParametricTestVariation1Test
extends AbstractOriginalToBeParameticizedTest {
public NewParametricTestVariation1Test() {
super("Some parameter", 1);
}
}
// add others here
}
@ParameterizedTest()
@MethodSource("dataProvider")
void testWithDataProvider(String str, List<JSONObject> list) {
System.out.println();
}
static Stream<Arguments> dataProvider() {
String json = """
{
"test":1
}
""";
return Stream.of(
arguments("abc", Arrays.asList(new JSONObject(json))),
arguments("lemon", Arrays.asList(new JSONObject(json)))
);