参数类
class Criteria {
private Map params;
public getMap(){ return params; }
}
并且服务方法接受此条件
class Service{
public List<Person> query(Criteria criteria){ ... }
}
自定义featureMatcher用于匹配条件键
private Matcher<Criteria> hasCriteria(final String key, final Matcher<?> valueMatcher){
return new FeatureMatcher<Criteria, Object>((Matcher<? super Object>)valueMatcher, key, key){
@Override protected Object featureValueOf(Criteria actual){
return actual.getMap().get(key);
}
}
}
使用mockito来证实参数:
verify(Service).query((Criteria) argThat("id", hasCriteria("id", equalTo(new Long(12)))));
错误消息显示:
Argument(s) are different! Wanted:
Service.query(
id <12L>
);
-> at app.TestTarget.test_id (TestTarget.java:134)
Actual invocation has different arguments:
Service.query(
app.Criteria@509f5011
);
如果我使用ArugmentCaptor
,
ArgumentCaptor<Criteria> argument = ArgumentCaptor.forClass(Criteria.class);
verify(Service).query(argument.capture());
assertThat(argument.getValue(), hasCriteria("id", equalTo(new Long(12))));
信息要好得多:
Expected: id <12L> but id was <2L>
如何在不使用ArgumentCaptor
的情况下收到此类消息?
答案 0 :(得分:1)
简短的回答是调整Criteria
代码,如果它在您的控制之下,则编写更好的toString
方法。否则,您最好使用ArgumentCaptor
方法。
为什么没有ArgumentCaptor会很难?你知道你期待一个电话,但即使你有十几个类似的评估电话,Mockito也会设计来处理它。即使您使用相同的匹配器实现,并使用相同的有用describeMismatch
实现,assertThat
本身也会尝试一次以匹配verify
看到不匹配的位置并保持不变试图匹配任何其他电话。
考虑一下:
// in code:
dependency.call(true, false);
dependency.call(false, true);
dependency.call(false, false);
// in test:
verify(mockDependency).call(
argThat(is(equalTo(true))),
argThat(is(equalTo(true))));
在这里,Mockito不知道哪个电话应该是call(true, true)
;这三个中的任何一个都可能是它。相反,它只知道您所期望的验证从未得到满足,并且三个相关呼叫中的一个可能已经接近。在使用ArgumentCaptor
的代码中,您可以使用您的知识,即只有一个调用,并提供更合理的错误消息;对于Mockito来说,它能做的最好的事情就是输出它收到的所有电话,而toString
没有有用的Criteria
输出,这根本就没有用。