首页 > 解决方案 > 具有列表参数内容的 Mockito 模拟对象

问题描述

我经常遇到这种情况,不知道如何使用 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));

无论如何我可以做到这一点吗?请记住,上面的代码只是抓住问题的一个例子,实际情况有点复杂,我只能模拟单个对象,而不是列表本身

谢谢

标签: javajunitmockitopowermockitohamcrest

解决方案


没关系,后来我了解到 Mockito 的 eq() 方法会在参数上调用 equals() 方法。现在,如果那是一个 ArrayList,则意味着如果两个列表大小相等,并且列表中每个元素的相等比较也返回 true,它将返回 true。请参阅https://docs.oracle.com/javase/6/docs/api/java/util/List.html#equals%28java.lang.Object%29

对于更多的自定义,可以使用 argThat() Mockito Matchers isA、any、eq 和 same 有什么区别?


推荐阅读