【问题标题】:Java Arguments.of() in a test case: How does it work?测试用例中的 Java Arguments.of():它是如何工作的?
【发布时间】:2020-10-09 14:31:32
【问题描述】:

我得到了参数化的测试用例,并使用了我不熟悉的 Stream.of 和 A​​rguments.of。如下所示,测试用例引用了我的类 BofAAdapter 的构造函数并传递了一个 BofA 对象。我想知道如何在我的班级中访问整数(500)和条目映射,或者它们被传递到哪里。我无法编辑测试用例,所以我不能简单地让它们使用不同的构造函数进行测试。我只是迷失在这个测试正在做什么。

@ParameterizedTest
    @MethodSource("providerBankAccountsGetDelinquent")
    public void testBankAccountsGetDelinquent(IBankAccounts adapter, int threshold, Map<Integer, Integer> expected) {
        Map<Integer, Integer> actual = adapter.getDelinquent( threshold );
        assertEqualMaps( expected, actual );
    }
    static Stream<Arguments> providerBankAccountsGetDelinquent() {
        return Stream.of(
                Arguments.of( new BofAAdapter( new BofA() ), 500, 
                        Map.ofEntries(
                            Map.entry( 1, 500),
                            Map.entry( 5,  20)
                        )),

【问题讨论】:

    标签: java testing arguments


    【解决方案1】:

    Arguments 是来自junit 5 的概念。

    您可以在上面链接的 junit 网站上了解 Arguments 的内容和使用方法,以及这里发生的事情。

    给你一个快速的概述:通常,一个测试方法没有参数。测试框架 (junit5) 将看到 @Test 注释并运行它。

    但这是一个不同的野兽:这个测试方法有..参数!试想一下测试框架:你会如何调用它? 'adapter' 和 'treshold' 你怎么理解?

    这就是 @MethodSource 注释的含义:它告诉 junit:首先,运行 providerBankAccountsGetDelinquent 方法,junit 可以这样做,因为没有要传递的参数。然后获取此方法提供给您的参数,它是一个流(因此,Arguments 类的任意数量的实例),并为您获得的每个 Arguments 对象运行此测试方法一次。

    所以,这最终会发生:

    1. junit 调用 providerBankAccountsGetDelinquent
    2. junit 得到一个Stream&lt;Arguments&gt; 对象。
    3. junit 将开始遍历流。
    4. 流将返回它将返回的第一个(也是唯一一个)对象:阈值 = 500 的 Arguments 对象、新的 BofAAdapter 等。
    5. 然后它将使用这些参数调用 testBankAccountsGetDelinquent 并根据测试结果打印“成功”或“失败”(这取决于这些映射是否相等)
    6. junit 向流请求下一个对象。
    7. 流说:不,我全力以赴,我只有一个 Arguments 对象。
    8. 这部分测试序列现已完成。

    换句话说,所有这些代码都是一种复杂而愚蠢的编写方式:

    @Test
    public void testBankAccountsGetDelinquent() {
        IBankAccounts adapter = new BofAAdapter( new BofA() );
        int threshold = 500;
        Map<Integer, Integer> expected = Map.ofEntries(
                                Map.entry( 1, 500),
                                Map.entry( 5,  20)
                            );
        Map<Integer, Integer> actual = adapter.getDelinquent( threshold );
        assertEqualMaps(expected, actual);
    }
    

    当然,大概这段代码要么是向您展示@ParameterizedTest 工作原理的示例,要么有人计划扩展providerBankAccountsGetDelinquent

    请注意,总体思路是您使用此@ParameterizedTest 机制来创建动态输入。例如,想象一下,您想对从 400 到 500 的所有阈值运行此测试,同时地图也会发生变化。那么这是一种方法。

    【讨论】:

      猜你喜欢
      • 2015-08-09
      • 1970-01-01
      • 2018-09-13
      • 2014-07-14
      • 2013-10-31
      • 2017-10-06
      • 1970-01-01
      • 1970-01-01
      • 2013-06-17
      相关资源
      最近更新 更多