简体   繁体   English

测试用例中的 Java Arguments.of():它是如何工作的?

[英]Java Arguments.of() in a test case: How does it work?

I've been given test cases that are parameterized and use Stream.of and Arguments.of which I am not familiar with.我得到了参数化的测试用例,并使用我不熟悉的 Stream.of 和 Arguments.of。 As evidenced below the test case references the constructor of my class BofAAdapter and passes a BofA object. I'm wondering how to access in my class the integer (500) and the map of entries, or where they are being passed.如下所示,测试用例引用了我的 class BofAAdapter 的构造函数并传递了 BofA object。我想知道如何在我的 class 中访问 integer (500) 和 map 条目,或者它们被传递到哪里。 I can't edit the test cases so I can't simply have them test with a different constructor.我不能编辑测试用例,所以我不能简单地让它们用不同的构造函数进行测试。 I'm just pretty lost here with what this test is doing.我对这个测试所做的很迷茫。

@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)
                        )),

Arguments is a concept from junit 5 . Argumentsjunit 5的概念。

You can read about what Arguments is about and how to use it, and what's happening here over at the junit site linked above.您可以在上面链接的 junit 网站上了解 Arguments 的内容和使用方法,以及这里发生的事情。

To give you a quick overview: normally, a test method has no arguments. The test framework (junit5) will see a @Test annotation and will just run it.给你一个快速概览:通常,测试方法没有 arguments。测试框架 (junit5) 将看到@Test注释并运行它。

But this is a different beast: This test method has.. parameters: Walk in the shoes of the test framework for a moment?但这是一个不同的野兽:这个测试方法有..参数:试一下测试框架? How would you invoke this?你将如何调用它? What do you pass for 'adapter' and 'treshold'?您将什么传递给“适配器”和“阈值”?

That's what the @MethodSource annotation is about: It's telling junit: FIRST, run the providerBankAccountsGetDelinquent method, which junit can do, because there are no arguments to pass.这就是@MethodSource注释的含义:它告诉 junit:首先,运行providerBankAccountsGetDelinquent方法,junit 可以执行该方法,因为没有 arguments 要传递。 Then take the arguments that this method gave you, which is a stream (so, any number of instances of the Arguments class), and run this test method once for each Arguments object you got.然后获取此方法为您提供的 arguments,它是一个 stream(因此, Arguments类的任意数量的实例),并针对每个 Arguments object 运行此测试方法一次。

So, this ends up happening:所以,这最终发生了:

  1. junit calls providerBankAccountsGetDelinquent junit 调用 providerBankAccountsGetDelinquent
  2. junit gets a Stream<Arguments> object. junit 得到一个Stream<Arguments> object。
  3. junit will start iterating through the stream. junit 将开始迭代 stream。
  4. The stream will return the first (and only) object it will ever return: An Arguments object with threshold = 500, a new BofAAdapter, etc. stream 将返回它永远返回的第一个(也是唯一一个)object:阈值为 500 的 Arguments object,一个新的 BofAAdapter 等。
  5. It will then invoke testBankAccountsGetDelinquent with those arguments and print 'succeed' or 'fail' depending on the result of that test (which will depend on whether those maps are equal)然后它将使用那些 arguments 调用testBankAccountsGetDelinquent并根据该测试的结果打印“成功”或“失败”(这将取决于这些映射是否相等)
  6. junit asks the stream for the next object. junit 向 stream 询问下一个 object。
  7. The stream says: Nope, I'm all out, that one Arguments object is all I had. stream 说:不,我全力以赴,那个 Arguments object 是我所有的。
  8. This part of the testing sequence is now complete.这部分测试序列现已完成。

In other words, all that code is a convoluted and silly way to just write:换句话说,所有这些代码都是一种复杂而愚蠢的编写方式:

@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);
}

Of course, presumably this code is either an example to show you how @ParameterizedTest works, or someone has a plan to expand on providerBankAccountsGetDelinquent .当然,大概这段代码是向您展示@ParameterizedTest工作原理的示例,或者有人计划扩展providerBankAccountsGetDelinquent

Note that the general idea is that you use this @ParameterizedTest mechanism to create dynamic inputs.请注意,一般的想法是您使用此@ParameterizedTest机制来创建动态输入。 Imagine, for example, you want to run this test for all thresholds from 400 to 500, with the map changing too.想象一下,例如,您想要对从 400 到 500 的所有阈值运行此测试,并且 map 也发生变化。 Then this is one way to do that.那么这是做到这一点的一种方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM