我想这样做:
when(myObject.getEntity(1l,usr.getUserName()).thenReturn(null);
when(myObject.getEntity(1l,Constants.ADMIN)).thenReturn(null);
与匹配器在一行中。所以,我有这个代码:
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
import static org.mockito.AdditionalMatchers.*;
[...]
User usr = mock(usr);
[...]
when(myObject.getEntity(
eq(1l),
or(eq(usr.getUserName()),eq(Constants.ADMIN))
)
).thenReturn(null);
但是当我使用Or matcher时,JUnit失败了:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
0 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"));
For more info see javadoc for Matchers class.
at blah.blah.MyTestClass.setup(MyTestClass:The line where I use the when & or matcher)
... more stacktrace ...
我做错了什么?
谢谢!
答案 0 :(得分:4)
因为usr
是模拟,所以内联方法调用usr.getUserName()
是让你失望的部分。出于特定于Mockito实现和语法聪明的原因,您无法在存根另一种方法的过程中调用模拟方法。
when(myObject.getEntity(
eq(1l),
or(eq(usr.getUserName()),eq(Constants.ADMIN))
)
).thenReturn(null);
调用像eq
和or
这样的Mockito匹配器实际上返回虚拟值,如0和null,以及 - 作为副作用 - 他们将Matcher行为添加到名为的堆栈中ArgumentMatcherStorage。一旦Mockito在模拟上看到方法调用,它会检查堆栈以查看它是否为空(即检查所有参数的相等性)或被调用方法的参数列表的长度(即使用堆栈上的匹配器,一个每个参数)。还有别的错误。
鉴于Java的评估顺序,您的代码会评估eq(1l)
第一个参数,然后usr.getUserName()
评估第二个参数 - or
的第一个参数。请注意,getUserName
不带参数,因此预期 0匹配器,并记录1个。
这应该可以正常工作:
String userName = usr.getUserName(); // or whatever you stubbed, directly
when(myObject.getEntity(
eq(1l),
or(eq(userName),eq(Constants.ADMIN))
)
).thenReturn(null);
要了解有关Mockito匹配器如何在幕后工作的更多信息,请参阅我的other SO answer here。