Mockito: InvalidUseOfMatchersException

本文介绍了一种在使用PowerMock进行单元测试时遇到的InvalidUseOfMatchersException错误及其解决方案。错误源于混合使用Matchers和原始值,正确的做法是所有参数都通过Matchers提供。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在项目中采用powermock进行单元测试,发现使用Matchers结果报如下错误

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
4 matchers expected, 3 recorded:
-> at com.yihaodian.wap.service.AddressServiceTest.testInsertGoodReceiverByTokenV2(AddressServiceTest.java:136)
-> at com.yihaodian.wap.service.AddressServiceTest.testInsertGoodReceiverByTokenV2(AddressServiceTest.java:136)
-> at com.yihaodian.wap.service.AddressServiceTest.testInsertGoodReceiverByTokenV2(AddressServiceTest.java:136)

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.

原始代码如下:

httpHelpMock.callShopInterfaceObj("addGoodReceiver", Matchers.any(Object[].class), Matchers.any(Type.class),"/myyhdmobile/address/addGoodReceiver.do",true);


public void callShopInterfaceObj(String methodName, Object[] objs,Type t,String shopurl2,Object reObj){
		PowerMockito.when(HttpHelper.callShopInterfaceObj(methodName, objs, t, shopurl2)).thenReturn(reObj);
	}

怎么也调试不出来

最后查看了这篇文章

http://stackoverflow.com/questions/14845690/mockito-invaliduseofmatchersexception

做修改如下:

httpHelpMock.callShopInterfaceObj(Matchers.eq("addGoodReceiver"), Matchers.any(Object[].class), Matchers.any(Type.class),Matchers.eq("/myyhdmobile/address/addGoodReceiver.do"),true);

主要差异是对传入的字符串做了Matchers.eq()动作

原因:使用Matchers不能只针对部分参数,所有参数都应该采用Matchers

<think>嗯,用户问的是关于Mockito中的InvalidUseOfMatchersException异常,特别是提到参数匹配器位置错误或滥用的情况。首先,我得回想一下自己使用Mockito时的经验,什么时候会遇到这个错误。通常,当使用参数匹配器(比如any()、eq()等)时,如果使用不当,比如部分参数用了匹配器而其他参数没用,或者在某些不支持的地方用了,就会抛出这个异常。 首先,要解释这个异常发生的原因。可能的情况包括:在参数列表中混合使用匹配器和具体值,或者在某些特殊的方法调用中错误使用匹配器,比如在验证或存根时的when()方法里。例如,当使用anyInt()作为参数匹配器时,其他所有参数也必须使用匹配器,而不能直接使用具体值,除非用eq()包裹具体值。 然后,需要给出具体的例子来说明正确的用法和错误的用法之间的区别。比如,错误的写法可能是when(mock.method(anyInt(), 5)).thenReturn(...),这里第一个参数用了anyInt(),而第二个参数用了具体值5,没有用eq(5),这样就会导致异常。正确的做法是使用eq(5)来包裹具体值。 另外,还要注意在存根方法时,如果使用了参数匹配器,所有参数都必须使用匹配器,不能部分使用。比如,正确的写法是when(mock.method(anyInt(), eq(5))).thenReturn(...)。 接下来,需要提供解决这个问题的步骤或方法,帮助用户避免这个错误。比如,检查所有参数是否都正确使用了匹配器,或者在需要具体值的地方使用eq()方法。另外,还要提醒用户注意某些Mockito版本中的限制,或者是否有其他替代方案。 最后,根据用户的问题,生成相关的后续问题,比如参数匹配器的作用,如何正确使用eq(),常见的参数匹配器有哪些,以及如何调试这类异常。这些问题可以帮助用户进一步理解和避免类似的问题。</think><< `org.mockito.exceptions.misusing.InvalidUseOfMatchersException` 是 Mockito 框架中常见的异常,表明在参数匹配器(Argument Matchers)的使用中存在错误。该异常通常发生在以下场景: ### **原因分析** 1. **混合使用匹配器和具体值** 当在方法调用参数中部分使用匹配器(如 `any()`, `eq()`)而另一部分直接使用具体值时,Mockito 无法正确解析参数规则。 ```java // 错误示例:第二个参数未用匹配器 when(mock.method(anyInt(), 5)).thenReturn("result"); // 正确写法:所有参数均使用匹配器 when(mock.method(anyInt(), eq(5))).thenReturn("result"); ``` 2. **匹配器未覆盖所有参数** 如果方法有多个参数,必须对所有参数使用匹配器,或全部使用具体值。不能部分使用。 3. **在非存根/验证上下文中使用匹配器** 匹配器只能在 Mockito 的 `when()`、`verify()` 等方法内部使用,不能用于普通代码中。 4. **在不可变参数位置使用匹配器** 如尝试在 `thenReturn()`、`thenThrow()` 的参数中使用 `any()` 等匹配器(这些位置需要具体值)。 --- ### **解决方法** 1. **统一使用匹配器** 确保所有参数要么使用匹配器,要么使用具体值(通过 `eq()` 包装具体值): ```java // 正确示例:所有参数均用匹配器 when(userService.findUser(eq("Alice"), anyInt())).thenReturn(new User()); ``` 2. **避免在非存根代码中使用匹配器** 匹配器仅用于 `when()`、`verify()` 等方法的参数定义中。 3. **检查链式调用中的匹配器** 如果方法调用链中有多个参数,需确保所有层级均正确使用匹配器: ```java // 错误示例:链式调用中部分使用匹配器 when(mock.getList(anyInt()).get(5)).thenReturn("value"); // 正确写法:显式定义链式调用的参数 when(mock.getList(anyInt())).thenReturn(someList); when(someList.get(5)).thenReturn("value"); ``` --- ### **调试建议** - 使用 `validateMockitoUsage()` 主动验证 Mockito 的用法: ```java @After public void tearDown() { Mockito.validateMockitoUsage(); // 捕获潜在的匹配器滥用 } ``` - 检查堆栈跟踪中提示的行号,定位具体哪个匹配器被误用。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值