我在测试中使用以下代码,该测试使用Mockito框架来验证方法drawTextOnCanvas()是否使用正确的参数调用.
// The two objects below are mocks. The rest of the objects used in
// the call to verify() are plain old java objects I've instantiated elsewhere.
BufferedImage testImage = Mockito.mock(BufferedImage.class);
Mockito.when(testImage.getHeight()).thenReturn(10);
Graphics mockGraphics = Mockito.mock(Graphics.class);
Mockito.when(mockGraphics.getFontMetrics(Matchers.any(Font.class)))
.thenReturn(Mockito.mock(FontMetrics.class));
Mockito.verify(drawingUtil).drawTextOnCanvas(
Matchers.eq(imageCategory.getWidth()),
Matchers.eq(mockGraphics),
Matchers.any(Font.class),
Matchers.eq(Arrays.asList("Test text")),
Matchers.eq(testImage.getHeight() + 10),
Matchers.any(FontMetrics.class),
Matchers.eq(10));
但是它抛出以下异常:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
0 matchers expected, 4 recorded:
-> at com.test.package(ExampleTest.java:66)
-> at com.test.package(ExampleTest.java:67)
-> at com.test.package(ExampleTest.java:67)
-> at com.test.package(ExampleTest.java:68)
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"));
For more info see javadoc for Matchers class........
然而,我发现如果我更换线路
Matchers.eq(testImage.getHeight() + 10),
同
Matchers.eq(someInteger),
测试运行没有例外,这让我很困惑.
我已经查看了JavaDoc for Matchers,并且我可以看到我写的内容应该可以工作,除非有一些关于在我错过的eq()调用中调用mock对象的规则.
最佳答案 你已经钉了它:你已经模拟了testImage,并且在不允许存根时调用mock方法.文件不清楚该限制.
我之前在Mockito匹配器上写了an exhaustive answer(参见“实现细节”),但是短版本是Mockito将其参数保持在堆栈上并且每次调用模拟的n参数方法都会检查堆栈是否包含0或n个匹配器.
Mockito.verify(drawingUtil).drawTextOnCanvas(
Matchers.eq(imageCategory.getWidth()), // A1
Matchers.eq(mockGraphics), // A2
Matchers.any(Font.class), // A3
Matchers.eq(Arrays.asList("Test text")), // A4
Matchers.eq(testImage.getHeight() + 10), // B
Matchers.any(FontMetrics.class), // C1
Matchers.eq(10)); // C2
调用顺序是这样的:在验证(drawingUtil)之后,Java按顺序准备drawTextOnCanvas的参数,调用A1到A4.突然发生了对B的调用,Mockito准备好像textImage.getHeight()嵌入在when(…)调用中.堆栈上有4个匹配器,Mockito希望通过相等(零匹配器)或getHeight()(也是零匹配器)的参数数来匹配.在获得C1,C2或drawTextOnCanvas之前,Mockito抛出了“4匹配记录”消息的异常.
作为一个好的做法,将所有Matchers.eq值(包含方法调用)提取到局部变量,特别强调对模拟对象的调用.