【问题标题】:Mockito - How to restrict list type with list matchers?Mockito - 如何使用列表匹配器限制列表类型?
【发布时间】:2016-08-02 11:12:35
【问题描述】:

我有如下界面:

public interface ListHandler {

    public boolean add(List<?> list, Object element);

}

为此,我想在测试中确保它只接收特定类型的列表,例如String。我编写了以下测试代码:

@Test
public void testAddOnlyString() {
    boolean actual = false;

    when(this.listHandlerMock.add(
        Matchers.anyListOf(String.class),
        Matchers.anyString()
    )).thenReturn(true);

    actual = this.listHandlerMock.add(new ArrayList<Integer>(), 1);
    assertTrue(actual);

    verify(this.listHandlerMock).add(
        Matchers.anyListOf(String.class),
        Matchers.anyString()
    );
}

但测试正确通过。

【问题讨论】:

  • 由于泛型类型擦除,所以您在运行时不知道泛型类型。我猜anyListOf 匹配器所做的是检查列表中的所有元素是否属于这种类型,但由于列表为空,它永远不会失败。不管怎样,你知道你要通过什么清单——你为什么要在任何清单上断言?只需提取到list = new ArrayList&lt;Integer&gt; 并期待相同的对象:sameInstance(list)
  • 顺便问一下,你的实物在哪里?测试所做的只是与模拟交互。你在这里测试什么?

标签: java unit-testing junit mocking mockito


【解决方案1】:

简短的回答:你不能。列表的类型在编译时被清除(类型擦除) 例如,这将打印true:

System.out.println(new ArrayList<Integer>().equals(new ArrayList<String>()));

同样来自Matchers.anyListOf的文档:

这个方法不做任何类型检查,它只是为了避免 输入你的代码。

如果列表不为空,您可以构建一个匹配器来检查每个条目是否具有您期望的类型,但对于空列表,您无能为力。

【讨论】:

  • 那么,这些匹配器的目的是什么?
  • @Julen {@link Matchers#anyList()} 的通用友好别名。它是 SuppressWarnings("unchecked") 的替代方法,可让代码保持编译器警告的清洁。
  • 警告是如何产生的?我正在尝试复制它以了解匹配器的含义。
  • @Julen 这是另一个问题;它是在编译时“生成”的;只是一个编译器警告
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-08
  • 2011-08-02
  • 1970-01-01
相关资源
最近更新 更多