【问题标题】:How to define display name using nested attributes of arguments in ParameterizedTest(name = #{index} multiply {0[0]} x {0[1]} = {0[2]})如何使用 ParameterizedTest 中的参数的嵌套属性定义显示名称(name = #{index} multiply {0[0]} x {0[1]} = {0[2]})
【发布时间】:2020-11-21 00:30:23
【问题描述】:

我无法确定它是否是缺少的功能,请参阅那里的 JUnit issue 1154my comment,或者只是我无法正确编写 JUnit5 中 @ParameterizedTestname 的语法.鉴于过去 3 年这个问题一直存在,恐怕我不能等到我得到答案甚至那里的实施,所以我也想在这里问。

在我的示例 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;
        }
    }
}

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

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

那么问题是 @ParametrizedTest(name) 定义符合我的预期?

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

【问题讨论】:

  • GitHub 上的人们非常活跃,他们为我提供了很好的解决方法/解决方案来满足我的需求。只需检查下面我的几个帖子:github.com/junit-team/junit5/issues/1154#issuecomment-666952289 正如我所说的那样,这是更多的解决方法,仍然很高兴知道到目前为止它是否是 JUnit5 的限制,或者当 int[] 作为传入时可以以某种方式实现论据
  • 您仍然可以发布解决方法作为答案。有总比没有好。

标签: java junit5 parametrized-testing


【解决方案1】:

好的,正如@Murat Karagöz 所建议的那样,我只是将我在Github 上收到的建议重新发布在一个地方。

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

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

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

然后代码如下:

private static Stream<Arguments> data() {
    return Stream.of(Arguments.of(1, 2, 2), Arguments.of(5, 3, 15), Arguments.of(121, 4, 484));
}

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

Marc Philipphis post @ Github 的积分转到Marc Philipp

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

sormarus 提供的This solution 建议使用@CsvSource 而不是@MethodSource,并在注释中提供测试数据集。

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

代码如下所示:

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

【讨论】:

    猜你喜欢
    • 2013-07-15
    • 1970-01-01
    • 2018-09-26
    • 1970-01-01
    • 2017-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多