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
"Invalid use of argument matchers" but I use matchers only
提问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 getHBaseConfiguration
with one argument that any
matches. That's why the error message says "0 matchers expected, 1 recorded": The 0 is for getHBaseConfiguration
and 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 匹配器时,请确保传递给匹配器的值都是预先计算好的:它们都应该是常量文字、简单的数学表达式或变量。任何涉及方法调用的内容都应该在存根/验证开始之前提取到局部变量。