是否有可能使用JUnit5的参数化新特性来运行测试类来接收测试参数,而不是在方法级执行?对于JUnit 4,可以使用@RunWith(Parameterized::class)这样的运行器加上继承来将参数数组传递给子类,但我不确定是否可以使用新的JUnit 5 API来实现等效的功能。
@RunWith(Parameterized::class)
suzh9iv81#
简短的回答无法使用JUnit 5按照JUnit 4的样式参数化 * 类创建 *。幸运的是,分离测试逻辑和测试输入数据(参数)的意图可以以不同的方式实现。
JUnit 5有自己的参数化测试方法,当然与JUnit 4不同。新方法不允许在类级别使用参数化的fixture,即即通过其每一种测试方法。因此,每个参数化的测试方法都应该显式地使用 link to parameters 进行注解。JUnit 5提供了大量的参数源类型,可以在文档和guides中找到
在您的示例中,从Junit 4的@Parameters迁移的最简单方法是使用@MethodSource或org.junit.jupiter.params.provider.*的@ArgumentsSource。[***] JUnit 4**:
@Parameters
@MethodSource
org.junit.jupiter.params.provider.*
@ArgumentsSource
@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[]。
value
String[]
一些备注和比较
在JUnit 4中,我们只能有一个提供参数的工厂方法,并且测试应该围绕这些参数构建。相反,JUnit 5在绑定参数方面提供了更多的抽象性和灵活性,并将测试逻辑与其参数解耦,这是次要的。这允许独立于参数源构建测试,并在需要时轻松更改它们。
依赖需求
参数化测试功能不包括在核心junit-jupiter-engine中,但位于单独的依赖项junit-jupiter-params中。
junit-jupiter-engine
junit-jupiter-params
vnjpjtjt2#
创建指定参数化的 meta注解,并将其应用于测试方法:
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) { /* ... */ } }
zkure5ic3#
@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))) );
我用这种方式绕过了这种复杂性
3条答案
按热度按时间suzh9iv81#
简短的回答
无法使用JUnit 5按照JUnit 4的样式参数化 * 类创建 *。
幸运的是,分离测试逻辑和测试输入数据(参数)的意图可以以不同的方式实现。
JUnit 5有自己的参数化测试方法,当然与JUnit 4不同。新方法不允许在类级别使用参数化的fixture,即即通过其每一种测试方法。因此,每个参数化的测试方法都应该显式地使用 link to parameters 进行注解。
JUnit 5提供了大量的参数源类型,可以在文档和guides中找到
在您的示例中,从Junit 4的
@Parameters
迁移的最简单方法是使用@MethodSource
或org.junit.jupiter.params.provider.*
的@ArgumentsSource
。[***] JUnit 4**:
JUnit 5(带
@MethodSource
):JUnit 5(带
@ArgumentsSource
):考虑到
@MethodSource
中的方法和@ArgumentsSource
中的类可以在任何地方描述,而不仅仅是在测试方法所在的同一个类中。此外,@MethodSource
允许提供多个源方法,因为它的value
是String[]
。一些备注和比较
在JUnit 4中,我们只能有一个提供参数的工厂方法,并且测试应该围绕这些参数构建。相反,JUnit 5在绑定参数方面提供了更多的抽象性和灵活性,并将测试逻辑与其参数解耦,这是次要的。这允许独立于参数源构建测试,并在需要时轻松更改它们。
依赖需求
参数化测试功能不包括在核心
junit-jupiter-engine
中,但位于单独的依赖项junit-jupiter-params
中。vnjpjtjt2#
创建指定参数化的 meta注解,并将其应用于测试方法:
zkure5ic3#
我用这种方式绕过了这种复杂性