即使所有论点都是“匹配器"类型,也会从调用 verify() 中获取 InvalidUseOfMatchersException [英] Getting InvalidUseOfMatchersException from call to verify() even though all arguements are of type 'Matchers'

查看:86
本文介绍了即使所有论点都是“匹配器"类型,也会从调用 verify() 中获取 InvalidUseOfMatchersException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 Mockito 框架的测试中有以下代码来验证方法 drawTextOnCanvas() 是否使用正确的参数调用.

I have the following code in a test which uses the Mockito framework to verify that the method drawTextOnCanvas() was called with the correct parameters.

    // 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........

然而我发现如果我更换线

I have however discovered that if I replace the line

 Matchers.eq(testImage.getHeight() + 10), 

 Matchers.eq(someInteger),

测试无一例外地运行,这让我感到困惑.

the test runs with no exceptions, which is what puzzles me.

我已经查看了 Matchers 的 JavaDoc,据我所知,我所写的应该可以工作,除非有一些规则将模拟对象的调用放在对 eq() 的调用中代码>我错过了.

I've looked at the JavaDoc for Matchers and as far as I can see what I've written should work, unless there is some rule about putting calls to mock objects inside a call to eq() that I've missed.

推荐答案

你已经搞定了:你已经模拟了 testImage,并且不允许在存根时调用模拟方法.文档并不清楚该限制.

You've nailed it: You've mocked testImage, and calling a mock method while stubbing is not allowed. The documentation is not clear on that limitation.

我之前写过关于 Mockito 匹配器的一个详尽的答案(参见实现详细信息"),但简短的版本是 Mockito 将其参数匹配器保存在堆栈上,并且每次调用模拟的 n 参数方法都会检查堆栈是否包含 0或 n 个匹配器.

I wrote an exhaustive answer on Mockito matchers before (see "implementation details"), but the short version is that Mockito keeps its argument matchers on a stack and that every call to a mocked n-argument method checks that the stack contains exactly 0 or n matchers.

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

调用顺序是这样的:在verify(drawingUtil)之后,Java按顺序准备参数给drawTextOnCanvas,调用A1到A4.突然对 B 的调用发生了,Mockito 准备好将 textImage.getHeight() 嵌入到 when(...) 调用中.堆栈上有 4 个匹配器,Mockito 期望通过相等(零匹配器)或 getHeight() 的参数数量(也是零匹配器)进行匹配.Mockito 甚至在到达 C1、C2 或 drawTextOnCanvas 之前就抛出了带有4 个匹配器记录"消息的异常.

The call order is something like this: After verify(drawingUtil), Java prepares the arguments to drawTextOnCanvas in order, calling A1 through A4. Suddenly the call to B happens, and Mockito prepares as if textImage.getHeight() were embedded within a when(...) call. There are 4 matchers on the stack, and Mockito expects either to match by equality (zero matchers) or the number of arguments to getHeight() (also zero matchers). Mockito throws that exception with that "4 matchers recorded" message before even getting to C1, C2, or drawTextOnCanvas.

作为一个好的做法,将所有 Matchers.eq 值(包含方法调用)提取到局部变量,特别强调对模拟对象的调用.

As a matter of good practice, extract all Matchers.eq values (that contain method calls) to local variables, with a particular emphasis on calls to mocked objects.

这篇关于即使所有论点都是“匹配器"类型,也会从调用 verify() 中获取 InvalidUseOfMatchersException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆