为什么IsIterableContainingInOrder Hamcrest匹配器无法使用数组?

时间:2012-09-19 18:47:30

标签: java junit hamcrest

我显然很困惑如何使用Hamcrest的IsIterableContainingInOrder来验证List等式,而不仅仅是使用.equals()。我想在报告中看到Hamcrest的有用信息。

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

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

特别地:

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

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


@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我意识到所有的惊讶都来自于我自己的无知而没有别的。我应该了解泛型,类型推理,varargs等等。我真的可以对此进行彻底的解释,我可能会在未来几次回顾它。

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)));
}

1 个答案:

答案 0 :(得分:6)

以下是aswers ...希望是正确的:)

// 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应该是List<List<String>>,因为只包含验证iteratable包含传递的项目

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

通过,因为array1被视为vararg。

// 4) & 5) 

与1相同

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

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

// 7)

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