Mockito:InvalidUseOfMatchersException

dev*_*ang 121 java unit-testing mockito

我有一个执行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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

public class InetAddressFactory {
    public InetAddress getByName(String host) throws UnknownHostException {
        return InetAddress.getByName(host);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的单元测试用例:

@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();
    }
}
Run Code Online (Sandbox Code Playgroud)

运行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"));
Run Code Online (Sandbox Code Playgroud)

关于如何解决这个问题的任何意见?

Rya*_*art 243

错误消息非常清楚地概述了解决方案.这条线

doNothing().when(cmd).dnsCheck(HOST, any(InetAddressFactory.class))
Run Code Online (Sandbox Code Playgroud)

当需要使用所有原始值或所有匹配器时,使用一个原始值和一个匹配器.可能会读取正确的版本

doNothing().when(cmd).dnsCheck(eq(HOST), any(InetAddressFactory.class))
Run Code Online (Sandbox Code Playgroud)

  • 我有多傻.我一直在分析为什么第二个参数一直给我错误.谢谢你的澄清.我是Mockito的新手,这是我第一次遇到. (8认同)

sam*_*sam 26

我很长一段时间都遇到了同样的问题,我经常需要混合使用Matchers和价值观,而我从未设法与Mockito合作......直到最近!我把解决方案放在这里,希望它能帮助某人,即使这篇文章很老了.

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

when(recommendedAccessor.searchRecommendedHolidaysProduct(eq(metas), any(List.class), any(HotelsBoardBasisType.class), any(Config.class)))
            .thenReturn(recommendedResults);
Run Code Online (Sandbox Code Playgroud)

在此示例中,"metas"是现有的值列表

  • 真棒.`org.mockito.Mockito.eq()` (4认同)
  • 正确的导入现在是org.mockito.ArgumentMatchers.eq() (4认同)

del*_*svb 13

它可能会对未来的某些人有所帮助:Mockito不支持嘲笑'最终'方法(现在).它给了我同样的东西InvalidUseOfMatchersException.

对我来说,解决方案是将方法的一部分放在一个单独的,可访问和可覆盖的方法中,而不必是'final'.

查看Mockito API以了解您的使用案例.