我经常遇到这种情况,并且不知道如何使用Mockito的默认方法(诸如any,anyList,eq)解决该问题
例如,我有一个对象,我想在其中模拟需要包含其他模拟对象的列表的方法。让我解释一下:
public class MyMapper {
public List<DataObjects> convertList(List<String> rawContents) {
rawContents.stream().map(r -> convertObject(r))
.collect(Collectors.toList());
}
public DataObject convertObject(String rawContent) {
return new DataObject(rawContent);
}
}
public class MyWorkerClass {
public boolean start(List<String> rawContents) {
List<DataObject> objects = new MyMapper().convertList(rawContents);
return publish(objects);
}
public boolean result publish(List<DataObject> objects) {
../// some logic
}
}
现在我想断言的是这样的。 注意:请假定在调用new()[使用某些PowerMockito]时返回正确的模拟
@Test
public void test() {
String content = "content";
DataObject mock1 = Mockito.mock(DataObject.class);
MyMapper mapperMock = Mockito.mock(MyMapper.class);
MyWorkerClass worker = new MyWorkerClass();
Mockito.when(mapperMock.convertObject(content)).thenReturn(mock1);
Mockito.when(worker.publish(eq(Arrays.asList(mock1)).thenReturn(true);
boolean result = worker.start(Arrays.asList(content));
Assert.assertTrue(result);
}
上面的代码存在问题
Mockito.when(worker.publish(eq(Arrays.asList(mock1)).thenReturn(true);
这将尝试匹配列表对象而不是列表内容,换句话说,即使我必须列出A:[mock1]和B:[mock1],A也不等于B,并且最终存根失败
我需要一种类似于hamcrest的contain
匹配器的匹配器。像这样:
Mockito.when(worker.publish(contains(mock1)).thenReturn(true));
反正我能做到吗?请记住,上面的代码只是解决问题的一个示例,实际情况稍微复杂一些,我只能模拟单个对象,而不能模拟列表本身
谢谢
答案 0 :(得分:0)
没关系,后来我了解到Mockito的eq()方法将在参数上调用equals()方法。现在,如果这是一个ArrayList,则意味着如果两个列表大小相等,并且列表中每个元素的相等比较也返回true,则它将返回true。参见https://docs.oracle.com/javase/6/docs/api/java/util/List.html#equals%28java.lang.Object%29
为了进行更多自定义,可以使用argThat()What's the difference between Mockito Matchers isA, any, eq, and same?