如何使用 ParameterizedTest 中参数的嵌套属性定义显示名称(name = #{index} multip {0[0]} x {0[1]} = {0[2]})

Del*_*hyM 5 java junit5 parametrized-testing

我无法确定它是否是一个缺失的功能,请参阅JUnit 问题 1154我在那里的评论,或者只是我无法正确编写 JUnit5 中的名称语法@ParameterizedTest。鉴于这个问题已经开放了三年,恐怕我等不及得到答案,甚至无法等到那里的实施,所以我也想在这里问。

在我的示例 ParameterizedTest 中,我使用@MethodSource,它返回一个整数数组流,我想仅使用这些数组的属性,而不是{arguments}使用 时所有相同的属性{0}。这里很难用语言解释,最好使用下面的代码示例。

package net.delphym.unittests;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertEquals;

class DynamicTestCreationTestParam {
    private static Stream<int[]> data() {
        return Stream.of(new int[][] { {1, 2, 2}, {5, 3, 15}, {121, 4, 484} });
    }

    @DisplayName("Multiplication test")
    @ParameterizedTest(name = "#{index} for {arguments}: {0} x {1} = {2}")
    @MethodSource("data")
    void testWithStringParameter(int[] data) {
        MyClass tester = new MyClass();
        int m1 = data[0];
        int m2 = data[1];
        int expected = data[2];
        assertEquals(expected, tester.multiply(m1, m2));
    }

    // class to be tested
    class MyClass {
        public int multiply(int i, int j) {
            return i *j;
        }
    }
}

Run Code Online (Sandbox Code Playgroud)

第一次运行的测试结果输出如下所示:#1 for [1, 2, 2]: [1, 2, 2] x {1} = {2}

理想情况下,我希望看到这个:#1 multiply: 1 x 2 = 2

所以问题是,符合我期望的@ParametrizedTest(名称定义是什么?)

我正在尝试这样的事情: name = "#{index} multiply : {[0][0]} x {[0][1]} = {[0][2]}" 但这在语法上是不正确的。

Del*_*hyM 1

好吧,按照@Murat Karag\xc3\xb6z的建议,我只是转发我在Github上收到的建议,以便将所有建议集中到一处。

\n

在我看来,毫无疑问,这些优雅的解决方案只是JUnit5 @ParameterizedTest的变通方法 API 限制的解决方法,但它们都满足了我的需求。

\n

如果我不需要使用建议的解决方法#1int[]

\n

这里提出的解决方案是保留@MethodSource("data")并仅更改其返回类型。现在,该data()方法返回Arguments对象流(每个 3 个),而不是int 数组流(每个 3 个)。

\n

然后代码如下:

\n
private static Stream<Arguments> data() {\n    return Stream.of(Arguments.of(1, 2, 2), Arguments.of(5, 3, 15), Arguments.of(121, 4, 484));\n}\n\n@DisplayName("Multiplication test")\n@ParameterizedTest(name = "#{index}: {0} x {1} = {2}")\n@MethodSource("data")\nvoid testWithStringParameter(int m1, int m2, int expected) {\n    MyClass tester = new MyClass();\n    assertEquals(expected, tester.multiply(m1, m2));\n}\n
Run Code Online (Sandbox Code Playgroud)\n

感谢Marc Philipp@Github 上的帖子

\n

建议的解决方法 #2 展开测试数据以满足显示需求##

\n

somarus提供的此解决方案建议使用@CsvSource而不是@MethodSource并在注释中提供测试数据集。

\n

我喜欢这个简单的例子,如何快速准备相同的基本变体,而不需要特定的数据生成方法。

\n

代码如下所示:

\n
    @DisplayName("Multiplication test")\n    @ParameterizedTest(name = "#{index} multiply: {0} x {1} = {2}")\n    @CsvSource({"1,2,2", "3,5,15", "121,4,484"})\n    void testWithStringParameter(int m1, int m2, int expected) {\n        MyClass tester = new MyClass();\n        assertEquals(expected, tester.multiply(m1, m2));\n    }\n
Run Code Online (Sandbox Code Playgroud)\n