10

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

我需要用 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);

问题是 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(其他两个句子也是如此)。但是怎么做?

4

3 回答 3

11

使用 Hamcrest 匹配器,如文档中所示:

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.
    }
}
于 2013-02-28T16:31:47.133 回答
2

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");
于 2020-01-24T09:45:40.767 回答
1

您需要正确实现MappingFilterequals()的方法。在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
于 2013-02-28T16:25:59.723 回答