Mockito:InvalidUseOfMatchersException


140

我有一个执行DNS检查的命令行工具。如果DNS检查成功,则该命令将继续执行其他任务。我正在尝试使用Mockito编写单元测试。这是我的代码:

public class Command() {
    // ....
    void runCommand() {
        // ..
        dnsCheck(hostname, new InetAddressFactory());
        // ..
        // do other stuff after dnsCheck
    }

    void dnsCheck(String hostname, InetAddressFactory factory) {
        // calls to verify hostname
    }
}

我正在使用InetAddressFactory模拟类的静态实现InetAddress。这是工厂代码:

public class InetAddressFactory {
    public InetAddress getByName(String host) throws UnknownHostException {
        return InetAddress.getByName(host);
    }
}

这是我的单元测试用例:

@RunWith(MockitoJUnitRunner.class)
public class CmdTest {

    // many functional tests for dnsCheck

    // here's the piece of code that is failing
    // in this test I want to test the rest of the code (i.e. after dnsCheck)
    @Test
    void testPostDnsCheck() {
        final Cmd cmd = spy(new Cmd());

        // this line does not work, and it throws the exception below:
        // tried using (InetAddressFactory) anyObject()
        doNothing().when(cmd).dnsCheck(HOST, any(InetAddressFactory.class));
        cmd.runCommand();
    }
}

运行testPostDnsCheck()测试异常:

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
2 matchers expected, 1 recorded.
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"));

关于如何解决这个问题有什么意见吗?

Answers:


283

错误消息概述了解决方案。线

doNothing().when(cmd).dnsCheck(HOST, any(InetAddressFactory.class))

当需要使用所有原始值或所有匹配器时,使用一个原始值和一个匹配器。正确的版本可能显示为

doNothing().when(cmd).dnsCheck(eq(HOST), any(InetAddressFactory.class))

8
我真傻 我一直在分析为什么第二个参数总是给我错误。感谢您的澄清。我对Mockito还是很陌生,这是我第一次遇到。
devang

32

我很长一段时间以来都遇到过同样的问题,我经常需要将Matchers和Values混在一起,直到最近我才设法用Mockito做到这一点。我将解决方案放在这里,希望即使这篇文章很旧也能对某人有所帮助。

显然不可能在Mockito中同时使用Matchers AND值,但是如果Matcher接受比较变量怎么办?那可以解决问题...实际上是:eq

when(recommendedAccessor.searchRecommendedHolidaysProduct(eq(metas), any(List.class), any(HotelsBoardBasisType.class), any(Config.class)))
            .thenReturn(recommendedResults);

在此示例中,“元”是现有值列表


5
太棒了 org.mockito.Mockito.eq()
javaPlease42 '16

4
正确的导入现在是org.mockito.ArgumentMatchers.eq()
sam

15

将来可能会有所帮助:Mockito不支持“最终”方法的模拟(现在)。它给了我同样的感觉InvalidUseOfMatchersException

对我来说,解决方案是将方法中不必“定型”的部分放在单独的,可访问的和可重写的方法中。

查看您的用例的Mockito API


这有助于弄清楚为什么我的kotlin代码会给我错误,因为kotlin中的所有方法都是最终的!
对不起,我_wont

0

尽管使用了所有匹配器,但我遇到了同样的问题:

"org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
1 matchers expected, 3 recorded:"

我花了很短的时间才弄清楚我要模拟的方法是一个类的静态方法(例如Xyz.class),它只包含静态方法,而我忘了写以下行:

PowerMockito.mockStatic(Xyz.class);

可能会帮助其他人,因为这也可能是问题的原因。


0

对于我的情况,引发异常是因为我尝试模拟package-access方法。当我将方法访问级别从更改packageprotected异常走。例如在Java类下面,

public class Foo {
    String getName(String id) {
        return mMap.get(id);
    }
}

该方法String getName(String id)必须处于最低 protected级别,这样模拟机制(子类)才能起作用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.