java Mockito:以复杂对象为参数的存根方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15140467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mockito: Stub method with complex object as a parameter
提问by Andres_age
Maybe this is a newbie question, but can't find the answer.
也许这是一个新手问题,但找不到答案。
I need to stub a method with Mockito. If the method has "simple" arguments, then I can do it. For example, a find method with two parameters, car color and number of doors:
我需要用 Mockito 存根一个方法。如果该方法具有“简单”参数,那么我可以做到。例如,一个 find 方法有两个参数,汽车颜色和门数:
when(carFinderMock.find(eq(Color.RED),anyInt())).thenReturn(Car1);
when(carFinderMock.find(eq(Color.BLUE),anyInt())).thenReturn(Car2);
when(carFinderMock.find(eq(Color.GREEN), eq(5))).thenReturn(Car3);
The problem is that the find argument is a complex object.
问题在于 find 参数是一个复杂的对象。
mappingFilter = new MappingFilter();
mappingFilter.setColor(eq(Color.RED));
mappingFilter.setDoorNumber(anyInt());
when(carFinderMock.find(mappingFilter)).thenReturn(Car1);
This code does not work. The error is "Invalid use of argument matchers! 1 matchers expected, 2 recorded".
此代码不起作用。错误是“参数匹配器的使用无效!预期有 1 个匹配器,已记录 2 个”。
Can't modify the "find" method, it needs to be a MappingFilter parameter.
不能修改“find”方法,它需要是一个MappingFilter参数。
I suppose that I have to do "something" to indicate Mockito that when the mappingFilter.getColor is RED, and mappingFilter.getDoorNumber is any, then it has to return Car1 (and the same for the other two sentences). But how?
我想我必须做“某事”来指示 Mockito,当 mappingFilter.getColor 是 RED 并且 mappingFilter.getDoorNumber 是 any 时,它必须返回 Car1(其他两个句子也是如此)。但是如何?
回答by JB Nizet
Use a Hamcrest matcher, as shown in the documentation:
使用 Hamcrest 匹配器,如文档中所示:
when(carFinderMock.find(argThat(isRed()))).thenReturn(car1);
where isRed()
is defined as
其中isRed()
定义为
private Matcher<MappingFilter> isRed() {
return new BaseMatcher<MappingFilter>() {
// TODO implement abstract methods. matches() should check that the filter is RED.
}
}
回答by Gopi
You need to correctly implement equals()
method of your MappingFilter. In equals()you should only compare color and not doorNumber.
您需要正确实现MappingFilter 的equals()
方法。在equals() 中,您应该只比较颜色而不是doorNumber。
In simplest form, it should look like this -
以最简单的形式,它应该是这样的——
@Override
public boolean equals(Object obj) {
MappingFilter other = (MappingFilter) obj;
return other.getColor() == this.getColor();
}
Also, you should form your MappingFilter simply as below instead of using any matcher such as eq
此外,您应该像下面这样简单地形成您的 MappingFilter,而不是使用任何匹配器,例如 eq
mappingFilter = new MappingFilter();
mappingFilter.setColor(Color.RED);
mappingFilter.setDoorNumber(10); //Any integer
回答by ?ukasz Wachowicz
Since 2.1.0Mockito has its own matcher mechanism build on top of org.mockito.ArgumentMatcher
interface. This allows to avoid using Hamcrest. Usage is almost of same as with Hamcrest. Keep in mind that ArgumentMatcher
is a functional interface and implementation of a matched can be expressed as a lambda expression.
从2.1.0 开始,Mockito 在org.mockito.ArgumentMatcher
界面之上建立了自己的匹配器机制。这允许避免使用 Hamcrest。用法几乎与 Hamcrest 相同。请记住,这ArgumentMatcher
是一个函数式接口,匹配项的实现可以表示为 lambda 表达式。
private ArgumentMatcher<SomeObject> isYellow() {
return argument -> argument.isYellow();
}
and then
接着
when(mock.someMethod(argThat(isYellow()).thenReturn("Hurray");