java “参数匹配器的使用无效”但我只使用匹配器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35683829/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 00:27:02  来源:igfitidea点击:

"Invalid use of argument matchers" but I use matchers only

javatestingjunitmockito

提问by Konstantin Zhukov

I get the error message:

我收到错误消息:

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Invalid use of argument matchers! 0 matchers expected, 1 recorded: -> at *.SegmentExportingTest.happyDay(SegmentExportingTest.java:37) This exception may occur if matchers are combined with raw values: //incorrect: someMethod(anyObject(), "raw String"); When using matchers, all arguments have to be provided by matchers. For example: //correct: someMethod(anyObject(), eq("String by matcher"));

org.mockito.exceptions.misusing.InvalidUseOfMatchersException:参数匹配器的使用无效!预期 0 个匹配器,记录 1 个:-> at *.SegmentExportingTest.happyDay(SegmentExportingTest.java:37) 如果匹配器与原始值组合,则可能发生此异常: //不正确:someMethod(anyObject(), "raw String"); 使用匹配器时,所有参数都必须由匹配器提供。例如: //正确:someMethod(anyObject(), eq("String by matcher"));

but in reality I use only matchers in arguments of the method.

但实际上我只在方法的参数中使用匹配器。

The next code is a source of the error above.

下一个代码是上述错误的来源。

ConfigReader configReader = mock(ConfigReader.class);
    when(configReader.getSparkConfig())
            .thenReturn(new SparkConf().setMaster("local[2]").setAppName("app"));
    when(configReader.getHBaseConfiguration()).thenReturn(new Configuration());

    SparkProfilesReader sparkProfilesReader = mock(SparkProfilesReader.class);
    ProfileSegmentExporter profileSegmentExporter = mock(ProfileSegmentExporter.class);

    //--
    new SegmentExporting().process(configReader, sparkProfilesReader, profileSegmentExporter);
    //--

    InOrder inOrder = inOrder(sparkProfilesReader, profileSegmentExporter);
    inOrder.verify(sparkProfilesReader).readProfiles(any(JavaSparkContext.class),
            refEq(configReader.getHBaseConfiguration()));

回答by Jeff Bowman

Resolved in the comments:

在评论中解决:

I extracted configReader.getHBaseConfiguration() in the separate line and the issue was hided.

我在单独的行中提取了 configReader.getHBaseConfiguration() 并隐藏了问题。

Your specific problem is that you're calling a mock method in the middle of setting up your matchers.

您的具体问题是您在设置 matchers 的过程中调用了一个模拟方法



The two lines that indicate the problem are these:

指示问题的两行是:

when(configReader.getHBaseConfiguration()).thenReturn(new Configuration());
// ...
inOrder.verify(sparkProfilesReader).readProfiles(any(JavaSparkContext.class),
    refEq(configReader.getHBaseConfiguration()));

As I wrote in a previous SO post, Mockito matchers work mostly via side-effects, so call order among Matcher methods and mock-object methods matters a lot to Mockito and its validation. The call to configReader.getHBaseConfiguration()is a call to a mock (as established in the first line) that happens after your call to any(JavaSparkContext.class), which confuses Mockito into thinking you're verifying zero-arg method getHBaseConfigurationwith one argument that anymatches. That's why the error message says "0 matchers expected, 1 recorded": The 0 is for getHBaseConfigurationand the 1 is any(JavaSparkContext.class).

正如我在之前的 SO 帖子中所写的那样,Mockito 匹配器主要通过副作用工作,因此 Matcher 方法和模拟对象方法之间的调用顺序对 Mockito 及其验证非常重要。对 的调用configReader.getHBaseConfiguration()是在调用 之后发生的对模拟的调用(如第一行中所建立)any(JavaSparkContext.class),这使 Mockito 误以为您正在getHBaseConfiguration使用any匹配的参数验证零参数方法。这就是为什么错误消息显示“0 个匹配器预期,1 个记录”:0 是 forgetHBaseConfiguration而 1 是any(JavaSparkContext.class)

To be safe, when using Mockito matchers, make sure the values passed to the matchers are all pre-calculated: They should all be constant literals, simple math expressions, or variables. Anything that involves a method call should be extracted to a local variable before stubbing/verifying begins.

为安全起见,在使用 Mockito 匹配器时,请确保传递给匹配器的值都是预先计算好的:它们都应该是常量文字、简单的数学表达式或变量。任何涉及方法调用的内容都应该在存根/验证开始之前提取到局部变量。