Mockito:InvalidUseOfMatchersException
Posted
技术标签:
【中文标题】Mockito:InvalidUseOfMatchersException【英文标题】:Mockito: InvalidUseOfMatchersException 【发布时间】:2013-01-28 12:50:27 【问题描述】:我有一个执行 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"));
关于如何解决这个问题的任何意见?
【问题讨论】:
【参考方案1】:可能对某人有帮助。模拟方法必须是模拟类,使用mock(MyService.class)
【讨论】:
【参考方案2】:不要使用 Mockito.anyXXXX()。直接将值传递给相同类型的方法参数。 示例:
A expected = new A(10);
String firstId = "10w";
String secondId = "20s";
String product = "Test";
String type = "type2";
Mockito.when(service.getTestData(firstId, secondId, product,type)).thenReturn(expected);
public class A
int a ;
public A(int a)
this.a = a;
【讨论】:
【参考方案3】:错误消息概述了解决方案。线
doNothing().when(cmd).dnsCheck(HOST, any(InetAddressFactory.class))
当需要使用所有原始值或所有匹配器时,使用一个原始值和一个匹配器。正确的版本可能是
doNothing().when(cmd).dnsCheck(eq(HOST), any(InetAddressFactory.class))
【讨论】:
我真傻。我一直在分析为什么第二个参数一直给我错误。感谢您的澄清。我对 Mockito 很陌生,这是我第一次遇到。 但是 eq() 需要两个参数。【参考方案4】:就我而言,引发异常是因为我试图模拟 package-access
方法。当我将方法访问级别从package
更改为protected
时,异常消失了。例如。在Java类下面,
public class Foo
String getName(String id)
return mMap.get(id);
方法String getName(String id)
必须至少 protected
级别,以便模拟机制(子类化)可以工作。
【讨论】:
【参考方案5】:尽管使用了所有匹配器,但我遇到了同样的问题:
"org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
1 matchers expected, 3 recorded:"
我花了一点时间才发现我试图模拟的方法是一个类的静态方法(比如 Xyz.class),它只包含静态方法,我忘了写以下行:
PowerMockito.mockStatic(Xyz.class);
可能会对其他人有所帮助,因为它也可能是问题的原因。
【讨论】:
【参考方案6】:它可能对将来的某个人有所帮助:Mockito 不支持模拟“最终”方法(现在)。它给了我同样的InvalidUseOfMatchersException
。
对我来说,解决方案是将方法中不必是“最终”的部分放在一个单独的、可访问且可覆盖的方法中。
查看Mockito API 以了解您的用例。
【讨论】:
这有助于弄清楚为什么我的 kotlin 代码会给我错误,因为 kotlin 中的所有方法都是最终的!【参考方案7】:我很长一段时间都遇到了同样的问题,我经常需要混合匹配器和值,而我从来没有用 Mockito 做到这一点......直到最近! 我将解决方案放在这里,希望即使这篇文章已经很老了,它也会对某人有所帮助。
显然不可能在 Mockito 中同时使用 Matchers AND values,但是如果有一个 Matcher 接受比较变量呢?这将解决问题......事实上有:eq
when(recommendedAccessor.searchRecommendedHolidaysProduct(eq(metas), any(List.class), any(HotelsBoardBasisType.class), any(Config.class)))
.thenReturn(recommendedResults);
在这个例子中,'metas' 是一个现有的值列表
【讨论】:
太棒了。org.mockito.Mockito.eq()
正确的导入现在是 org.mockito.ArgumentMatchers.eq()
非常感谢这个提示。谢谢山姆!以上是关于Mockito:InvalidUseOfMatchersException的主要内容,如果未能解决你的问题,请参考以下文章
单元测试(mock) 错误org.mockito.Mockito.framework()Lorg/mockito/MockitoFramework;解析
单元测试(mock) 错误org.mockito.Mockito.framework()Lorg/mockito/MockitoFramework;解析