使用Mockito匹配特定类型的空列表

时间:2016-10-13 23:47:12

标签: java unit-testing mockito

我有一个带一些参数的方法。其中一个是某个类的List,null是此参数的可接受值。

public void doStuff(String string, @Nullable List<SomeClass> list) {
    ...
}

我想编写一个使用Mockito来验证方法是否以null作为参数调用的测试。我尝试使用isNull(List.class)

MyClass myClass = ...
verify(myClass).doStuff(any(String.class), isNull(List.class));

但这会产生警告:

  

未经检查的转换
必需:java.util.List&lt;   com.package.SomeClass&gt;
发现:java.util.List

我可以看到如果列表不为null,如何修复此警告:

// this generates the same warning
verify(myClass).doStuff(any(String.class), any(List.class));

// this does not generate the warning
verify(myClass).doStuff(any(String.class), Matchers.anyListOf(SomeClass.class)));

然而,我似乎无法找到将这两种方法结合在一起的方法。或者找到一种替代方法来完成我想要做的事情。 (除了使用注释抑制警告外)

1 个答案:

答案 0 :(得分:1)

一般的答案是使用显式泛型方法参数。

verify(myClass).doStuff(any(String.class), Matchers.<List<SomeClass>>isNull());

附加说明:

  • 在实践中,警告并不能保护您免受任何伤害; nullnull,对于类型擦除,所有这些表单都将编译为相同的字节码。
  • Java 8可以从方法参数推断泛型类型,因此isNull()就足够了,没有聪明。
  • Mockito 1.x调用类org.mockito.Matchers,而Mockito 2.x则弃用该类,转而使用org.mockito.ArgumentMatchers。在这两种情况下,匹配器方法都可以通过org.mockito.Mockito看到,但是static-methods-via-inheritance在语义上很弱,并且可能导致这些方法不会出现在IDE中。
  • 如果没有<List<SomeClass>>isNull()作为静态参数,则无法指定Matchers。如果您需要做很多事情, 可以做的是提取本地静态方法......

    private static List<SomeClass> nullSomeClassList() {
      return isNull();  // Return value types can be inferred before Java 8.
    }
    
    // elsewhere
    verify(myClass).doStuff(any(String.class), nullSomeClassList());
    

    ......但无论你做什么,don't extract to a field instead。副作用在这里很重要。