PowerMockito单元测试中的Invalid use of argument matchers问题详解
PowerMockito单元测试中的Invalid use of argument matchers问题详解
首先,简单说说PowerMockito进行单元测试的三部曲:
- 打桩,即为非测试目标方法设置返回值,这些返回值在测试目标方法中被使用。
- 执行测试,调用测试目标方法。
- 验证测试结果,如测试方法是否被执行,测试结果是否正确等。
其次,在使用PowerMockito框架进行单元测试的过程中,经常遇到如下异常:
-
Invalid use of argument matchers! -
0 matchers expected, 1 recorded: -
-> at com.mycompany.myproject.mypackage.MyTestClass.myTestMethod(MyTestClass.java:65) -
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.
乍一看似乎找不到北,先看看下面的代码再说。
被测试方法如下:
-
public boolean toggleOffOn(int delaySeconds) { -
boolean off = powerOff(); -
sleep(delaySeconds); -
boolean on = powerOn(); -
return off && on; -
}
测试用例中的测试方法片段如下:
-
PowerMockito.when(ps.powerOn()).thenReturn(true); -
PowerMockito.when(ps.powerOff()).thenReturn(true); -
PowerMockito.when(ps.toggleOffOn(Mockito.anyInt())).thenReturn(true);//throws exception here
异常分析:
从异常的位置来看,该异常发生在打桩阶段,还未执行到真正的测试。
从异常的信息来看,显然违反了一个Mockito框架中的Matchers匹配参数的规则。根据Matchers文档如下,在打桩阶段有一个原则,一个mock对象的方法,如果其若干个参数中,有一个是通过Matchers提供的,则该方法的所有参数都必须通过Matchers提供。而不能是有的参数通过Matchers提供,有的参数直接给出真实的具体值。
-
If you are using argument matchers, all arguments have to be provided by matchers. -
E.g: (example shows verification but the same applies to stubbing): -
verify(mock).someMethod(anyInt(), anyString(), eq("third argument")); -
//above is correct - eq() is also an argument matcher -
verify(mock).someMethod(anyInt(), anyString(), "third argument"); -
//above is incorrect - exception will be thrown because third argument is given without argument matcher. -
Matcher methods like anyObject(), eq() do not return matchers. Internally, they record a matcher on a stack and return a dummy value (usually null).
上述文档中给出的示例,可以使用eq()方法将真实的具体值转换为Matchers提供的值。
解决方法:
给出具体值
PowerMockito.when(ps.toggleOffOn(3)).thenReturn(true);
或直接去掉(仅适用于该测试用例)
PowerMockito.when(ps.toggleOffOn(Mockito.anyInt())).thenReturn(true);
注意:在Mockito 1.x中,org.mockito.Matchers已经过时,org.mockito.Mockito继承自Matchers,用以取代Matchers。
参考链接:
http://static.javadoc.io/org.mockito/mockito-core/1.10.19/org/mockito/Matchers.html
更多推荐
所有评论(0)