【问题标题】:Junit5 Duplicated parameter in parameterized testJunit5参数化测试中的重复参数
【发布时间】:2021-06-10 04:15:44
【问题描述】:

我有一个函数,它接收两个对象并返回“最大”的一个。对于这个问题,“最大”的确定并不重要。我有一个参数化测试,如下所示:

@ParameterizedTest()
@MethodSource
void testGetLargest(Widget widget1, Widget widget2, Widget expectedLargestWidget) {
   var largestWidget = service.getLargestWidget(widget1, widget2);

   assertEquals(expectedLargestWidget, largestWidget);
}

private static Stream<Arguments> testGetLargest() {
    return Stream.of(
            Arguments.of(
                    Widget.builder().field1("something").field2("something else").build(),
                    Widget.builder().field1("second something").field2("second something else").build(),
                    **not sure what to put here**),
                    ...

如您所见,测试的第三个参数应该与前两个参数之一相同。虽然我可以复制代码并创建与前两个相同的第三个参数,但这感觉很混乱。

有没有一种方法可以构建参数,使我可以将与前两个中的一个相同的对象作为第三个参数传递?

或者在我的测试中,我可以引用现有参数之一作为第三个参数? 我考虑过让第三个参数是一个 int,它代表前两个参数之一的索引,然后使用反射,但这也感觉很重。

【问题讨论】:

  • 把你的测试改成一个数组,然后把索引传给最大的小部件?
  • 传递一个整数作为第三个参数很好,但是在尝试实际断言第一个对象是更大还是第二个时,它会给你带来很多痛苦(因为你必须将对象与整数进行比较),如一般的做法是在断言期间传递整个对象并检查其是否相等。

标签: java junit5


【解决方案1】:

我觉得你有点想多了,既然你知道哪个应该是最大的,你总是可以把预期的作为第一个参数,然后比较largestWidget和它,你只需要两个参数:

@ParameterizedTest()
@MethodSource
void testGetLargest(Widget widget1, Widget widget2) {
   var largestWidget = service.getLargestWidget(widget1, widget2);

   assertEquals(widget1, largestWidget);
}

【讨论】:

  • 谢谢@Qiu,您的回答非常适合我的示例,但它是我实际问题的简化版本。对于我的实际问题,我接受了两个不完全相同类型的对象,因此我没有灵活性来更改第一个参数。我也在寻找一种方法来两次传递相同的值,因此我无法将您的解决方案标记为答案。
  • @ssc327 没关系,您应该始终接受适合您需求的答案。
【解决方案2】:

您可以尝试@CsvSource,而不是@MethodSource
当我在一个参数化测试中需要 3 个整数参数时,我这样做了。
这是我的测试方法的签名:

@ParameterizedTest
@CsvSource("300,10,", "150,5,", "90,9,0", "100,0,10")
fun totalScoreTests(result: Int, firstThrow: Int, secondThrow: Int?)

它是 Kotlin 而不是 Java,但 JUnit 5 可用于两种语言。
如果您搜索“GameTest”,您可以在这篇博文中找到我的完整示例:
https://agile-coding.blogspot.com/2021/06/clean-code-dojo.html

【讨论】:

  • 谢谢,但是因为我正在构建复杂的对象,所以这不起作用
【解决方案3】:

这似乎是第二天重新审视会导致非常明显的答案的情况。我更新了我的 methodSource 函数以首先构建对象,然后传递对它们的引用,这使我可以重用对最大小部件的引用。

private static Stream<Arguments> testGetLargest() {
   Widget widget1 = Widget.builder().field1("something").field2("something else").build();
   Widget widget2 = Widget.builder().field1("second something").field2("second something else").build();
    return Stream.of(
            Arguments.of(
                    widget1,
                    widget2,
                    widget1),
                    ...

【讨论】:

    猜你喜欢
    • 2019-01-23
    • 2018-02-21
    • 2019-04-08
    • 2017-05-23
    • 2020-04-30
    • 2021-11-10
    • 1970-01-01
    • 1970-01-01
    • 2022-06-29
    相关资源
    最近更新 更多