如何使用具有特定属性的参数对方法进行 stub ?
例如:
doReturn(true).when(object).method(
// an object that has a property prop1 equals to "myprop1"
// and prop2 equals to "myprop2"
)
最佳答案
您将需要一个自定义的 Mockito 匹配器或 Hamcrest 匹配器来解决此问题,或者两者的混合。 The two work a little differently ,但您可以将它们与适配器一起使用。
与 Hamcrest
您需要使用 Matchers.argThat
(Mockito 1.x) 或 MockitoHamcrest.argThat
(Mockito 2.x) 来调整 Hamcrest hasProperty
匹配器并将其组合起来。
doReturn(true).when(object).method(
argThat(allOf(hasProperty("prop1", eq("myProp1")),
hasProperty("prop2", eq("myProp2"))))
)
这里,argThat
调整 Hamcrest 匹配器以在 Mockito 中工作,allOf
确保您只匹配满足两个条件的对象,hasProperty
检查对象,eq
(特别是 Hamcrest 的 eq
,而不是 Mockito 的 eq
)比较字符串相等性。
没有 Hamcrest
从 Mockito v2.0(现在处于测试版)开始,Mockito 不再直接依赖于 Hamcrest,因此您可能希望以类似的风格对 Mockito 的 ArgumentMatcher 类执行相同的逻辑。
doReturn(true).when(object).method(
argThat(new ArgumentMatcher<YourObject>() {
@Override public boolean matches(Object argument) {
if (!(argument instanceof YourObject)) {
return false;
}
YourObject yourObject = (YourObject) argument;
return "myProp1".equals(yourObject.getProp1())
&& "myProp2".equals(yourObject.getProp2());
}
})
)
当然,同样的自定义匹配器类技术也适用于 Hamcrest,但如果您确定正在使用 Hamcrest,您可能更喜欢上面的 hasProperty
技术。
重构
需要注意的是:尽管我们欢迎您按照自己的意愿保存 Matcher 对象(在静态帮助器方法中返回或保存在字段中),但对 argThat
has side effects 的调用,因此必须在调用方法
期间进行调用。换句话说,如果需要,可以保存并重用您的 Matcher
或 ArgumentMatcher
实例,但不要重构对 argThat
的调用,除非您这样做所以进入静态方法,因此argThat
仍然会在正确的时间被调用。
// GOOD with Hamcrest's Matcher:
Matcher<YourObject> hasTwoProperties = (...)
doReturn(true).when(object).method(argThat(hasTwoProperties));
// GOOD with Mockito's ArgumentMatcher:
ArgumentMatcher<YourObject> hasTwoProperties = (...)
doReturn(true).when(object).method(argThat(hasTwoProperties));
// BAD because argThat is called early:
YourObject expectedObject = argThat(...);
doReturn(true).when(object).method(expectedObject);
// GOOD because argThat is called correctly within the method call:
static YourObject expectedObject() { return argThat(...); }
doReturn(true).when(object).method(expectedObject());
关于java - 如何使用具有特定属性的参数对方法进行 stub ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37345213/