Mockito:以复杂对象作为参数的Stub方法

时间:2013-02-28 16:21:07

标签: java parameters mockito stub

也许这是一个新手问题,但找不到答案。

我需要使用Mockito存根方法。如果方法有“简单”参数,那么我就可以做到。例如,一个带有两个参数的查找方法,汽车颜色和车门数量:

 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);

问题是find参数是一个复杂的对象。

 mappingFilter = new MappingFilter();
 mappingFilter.setColor(eq(Color.RED));
 mappingFilter.setDoorNumber(anyInt());
 when(carFinderMock.find(mappingFilter)).thenReturn(Car1);

此代码不起作用。错误是“无效使用参数匹配器!1匹配器预期,2记录”。

无法修改“find”方法,它需要是MappingFilter参数。

我想我必须做“某事”来表示Mockito,当mappingFilter.getColor为RED,而mappingFilter.getDoorNumber为any时,则必须返回Car1(对于其他两个句子也是如此)。 但是如何?

3 个答案:

答案 0 :(得分:10)

使用Hamcrest匹配器,如the documentation

所示
when(carFinderMock.find(argThat(isRed()))).thenReturn(car1);

其中isRed()定义为

private Matcher<MappingFilter> isRed() {
    return new BaseMatcher<MappingFilter>() {
        // TODO implement abstract methods. matches() should check that the filter is RED.
    }
}

答案 1 :(得分:2)

您需要正确实施 MappingFilter equals()方法。在 equals()中,您应该只比较颜色而不是 doorNumber

最简单的形式,它应该是这样的 -

@Override
public boolean equals(Object obj) {
    MappingFilter other = (MappingFilter) obj;
    return other.getColor() == this.getColor();
}

此外,您应该如下所示形成MappingFilter,而不是使用任何匹配器,例如eq

 mappingFilter = new MappingFilter();
 mappingFilter.setColor(Color.RED);
 mappingFilter.setDoorNumber(10); //Any integer

答案 2 :(得分:1)

2.1.0 起,Mockito在org.mockito.ArgumentMatcher界面之上建立了自己的匹配器机制。这样可以避免使用Hamcrest。用法几乎与Hamcrest相同。请记住,ArgumentMatcher是一个功能接口,匹配项的实现可以表示为lambda表达式。

private ArgumentMatcher<SomeObject> isYellow() {
    return argument -> argument.isYellow();
}

然后

when(mock.someMethod(argThat(isYellow()).thenReturn("Hurray");