【问题标题】:Mockito mock object with list argument's contents具有列表参数内容的 Mockito 模拟对象
【发布时间】:2018-08-08 18:18:25
【问题描述】:

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

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

谢谢

【问题讨论】:

  • 不,这不是问题所在。问题是 MyWorkerClass 创建了自己的 MyMapper 实例并且 n 使用它。它不使用您的测试创建的模拟 MyMapper。该代码也无法编译。而且您正在尝试模拟真实对象(工作者)的方法。发布一个真实的编译示例,该示例实际上重现了该问题。
  • 正如我所说,代码只是一个参考。你可以假设有一些额外的 PowerMockito 存根在 new MyWorkerClass() 上返回正确的模拟
  • 问题是,如果我需要在一半的代码行上假设一些不同的东西,那么很难猜测实际问题是什么。因此,再次发布一个真实的编译示例,该示例实际上重现了该问题。

标签: java junit mockito powermockito hamcrest


【解决方案1】:

没关系,后来我了解到 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?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-21
    相关资源
    最近更新 更多