【问题标题】:Mockito doesn't correctly stub methods taking list as argumentMockito 没有正确地存根以列表为参数的方法
【发布时间】:2016-01-28 09:02:22
【问题描述】:

我试图模拟一个类并在调用模拟对象上的方法时返回一个对象的存根列表。让我们考虑以下代码:

interface MyRepositry{
       public List<MyClass> getMyClassInstances(String str,Long id,List<Integer> statusList);
}

我正在模拟上述方法调用如下:

when(myRepository.getMyClassInstances("1234", 200L, stubbedList)).thenReturn(stubbedMyClassInstanceList);

在哪里

 stubbedList 

是我通过插入两个整数 1 和 3 创建的列表。在实际调用中,我也传递了我构造的具有整数 1 和 3 的列表。注意这里是 stubbedList 对象和实际调用中的列表对象是不同的,但是总是包含两个整数 1 和 3。

stubbedMyClassInstanceList    

是 MyClass 实例的存根列表。

但是,当我运行测试时,mockito 返回一个空列表。我做了一些调试,我猜 mockito 无法匹配我在

中使用的列表对象
      when(..).thenReturn(..)

调用和实际调用,因此找不到正确的签名。

我不能用

anyList() 

匹配器,因为我总是传递两个整数(1 和 3)的列表。

我已经通过自定义解决了这个问题

     ArgumentMatcher 

如下:

     class StatusMatcher extends ArgumentMatcher<List> {
    public boolean matches(Object list) {
        List statuses = ((List) list);
        return (statuses.size() == 2 && statuses.contains(1) && statuses.contains(3));
    }
}

所以问题是:

1) 我猜测为什么存根/模拟不能正常工作吗? 2) 我使用的解决方案是否正确?

【问题讨论】:

  • 请提供一个完整(但简单)的工作示例来说明问题。
  • 我无法提供实际代码,因为它已授权给我工作的公司。但是我给出了最少的相关代码。如果您发现上述任何代码解释性不够,我可以解释更多。

标签: java unit-testing mockito stubbing argument-matcher


【解决方案1】:

Mockito 自然使用equals() 进行参数匹配。 List&lt;T&gt; 中的 equals() 方法指定如果两个列表包含相同顺序的相同元素,则它们被定义为相等。

您说有效的自定义参数匹配器没有考虑顺序。

那么可能List&lt;T&gt; 中的 1 和 3 的顺序错误?

【讨论】:

  • 或者List是不同的类型。
  • 我的自定义匹配器不检查订单它只是检查它是否包含正确的元素
  • List 属于相同类型,即 Integer 对象的 Arraylist
  • 我会检查订单
  • 验证方法是否被列表调用的解决方案,忽略列表中元素的顺序,可以找到here
【解决方案2】:

Mockito 有一个 eq() 方法

你可以试试:

import static org.mockito.Matchers.eq;

.....

when(myRepository.getMyClassInstances(eq("1234"), eq(200L), eq(stubbedList)).thenReturn(stubbedMyClassInstanceList);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-21
    • 1970-01-01
    • 2012-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多