2

我显然对如何使用 HamcrestIsIterableContainingInOrder来验证 List 相等性而不仅仅是使用.equals(). 我想在我的报告中看到 Hamcrest 的有用信息。

为什么下面的测试甚至无法编译?他们中的一些人比其他人更违反直觉,至少对我来说是这样。我认为,我得到的一般原则是类型参数将被推断为我传递给具有可变参数签名的方法的内容,因此它将 T 的数组视为 T 的可变参数,因此将基于 T 而不是基于T 的数组,T 的可迭代,或类似的东西。

我可以解释一下,为什么一些最直观的行实际上甚至无法编译。

特别:

  • 3和4展示了array/List的不对称性
  • 5 和 6 表明我可以查看列表而不是数组(?)

标记为这样的行上的编译器警告对我来说更加神秘。


@org.junit.Test
public void testTest() {
  String string1 = "A";
  String string2 = "B";
  String string3 = "C";

  List<String> list1 = Lists.newArrayList(string1, string2, string3);
  List<String> list2 = Lists.newArrayList(string1, string2, "C");

  String[] array1 = list1.toArray(new String[list1.size()]);
  String[] array2 = list2.toArray(new String[list2.size()]);

  // -------------------------------------------------------------------------
  // 1) The assertion after this comment line DOES NOT COMPILE
  // Assert.assertThat(array2, IsIterableContainingInOrder.contains(array1));
  // -------------------------------------------------------------------------
  // 2) The assertion after this comment line DOES NOT COMPILE
  // Assert.assertThat(list2, IsIterableContainingInOrder.contains(list1));
  // -------------------------------------------------------------------------
  // 3) The assertion after this comment line SUCCEEDS
  Assert.assertThat(list2, IsIterableContainingInOrder.contains(array1));
  // -------------------------------------------------------------------------
  // 4) The assertion after this comment line DOES NOT COMPILE + HAS WARNING
  // Assert.assertThat(array2, IsIterableContainingInOrder.contains(list1));
  // -------------------------------------------------------------------------
  // 5) The assertion after this comment line DOES NOT COMPILE
  // Assert.assertThat(array2, IsIterableContainingInOrder.contains(string1));
  // -------------------------------------------------------------------------
  // 6) The assertion after this comment line COMPILES but fails
  Assert.assertThat(list2, IsIterableContainingInOrder.contains(string1));
  // -------------------------------------------------------------------------
  // 7) The assertion after this comment line COMPILES and succeeds
  Assert.assertThat(list2,
      IsIterableContainingInOrder.contains(string1, string2, string3));
  // -------------------------------------------------------------------------
}

大量的惊讶。:(


PS我意识到所有的惊讶都来自我自己的无知,没有别的。我应该复习泛型、类型推断、可变参数等。我真的可以对此进行彻底的解释,并且我可能会在以后多次回顾它。

PPS我确实尝试过先阅读代码,但看了一下......;)不是为了装腔作势:

@SuppressWarnings("unchecked")
@Factory
public static <E> Matcher<Iterable<? extends E>> contains(final Matcher<? super E> itemMatcher) {
    return contains(new ArrayList<Matcher<? super E>>(asList(itemMatcher)));
}
4

1 回答 1

6

这是答案...希望是正确的:)

// 1) The assertion after this comment line DOES NOT COMPILE
// Assert.assertThat(array2, IsIterableContainingInOrder.contains(array1));

这个不编译,因为数组不实现Iteratable。

// 2) The assertion after this comment line DOES NOT COMPILE
// Assert.assertThat(list2, IsIterableContainingInOrder.contains(list1));

为此, list2 应该是 a List<List<String>>,因为 contains 仅验证可迭代对象是否包含传递的项目

// 3) The assertion after this comment line SUCCEEDS
Assert.assertThat(list2, IsIterableContainingInOrder.contains(array1));

通过,因为 array1 被视为可变参数。

// 4) & 5) 

与 1 相同

// 6) The assertion after this comment line COMPILES but fails
Assert.assertThat(list2, IsIterableContainingInOrder.contains(string1));

包含期望集合中的所有项目,而不仅仅是一个子集。

// 7)

与 3 类似,但每个项目都通过了。

于 2012-09-19T19:33:15.880 回答