如何检查数组是否是二维数组中的元素之一

时间:2017-07-27 15:07:55

标签: java junit hamcrest

我试图断言使用Hamcrest库提供的标准 Collection.isIn 匹配器,一个字符串元素数组是二维数组的元素之一。不幸的是收到以下断言异常:

java.lang.AssertionError: 
Expected: one of {["A", "B", "C"], ["A", "B", "C"]}
   but: was ["A", "B", "C"]

代码:

String[][] expected = new String[][] { { "A", "B", "C" }, { "A", "B", "C" } };
String[] actual = new String[] { "A", "B", "C" };

assertThat(actual, isIn(expected));

我可以用这种方式验证使用hamcrest吗?或者我是否需要为给定方案创建自己的匹配器?

5 个答案:

答案 0 :(得分:3)

问题在于Object.equals()在对象是数组时没有做到你所期望的。您可能已经知道,您必须使用Arrays.equals() - 但Hamcrest isIn()不允许这样做。

可能最简单的解决方案是转换为List,即使仅用于测试 - 因为List.equals()可以像Hamcrest那样工作:

String[][] expected = new String[][] { { "A", "B", "C" }, { "A", "B", "C" } };

Object[] expectedLists = Arrays.stream(expected).map(Arrays::asList).toArray();

String[] actual = new String[] { "A", "B", "C" };

assertThat(Arrays.asList(actual), isIn(expectedLists));

答案 1 :(得分:1)

您的数组可能包含与expected中的数组相同的内容,但它不是同一个对象。

答案 2 :(得分:1)

首先,您最好使用List<>代替数组。

其次,是的,如果你坚持使用数组,你需要编写自己的'array-contains-element'函数。您可以使用数组主要维度上的循环来实现此函数,调用Arrays.equals()方法来比较两个一维数组的内容。

答案 3 :(得分:0)

我猜测问题是因为该方法比较对象而不是内容。基本上,即使两者具有相同的内容,它们也不是同一个对象。 See here in the docs

请改为:

String[] actual = new String[]{"A1 C1 E1 F1 J1", "A1 C1 E1 F1 K1", "A1 B1 G1 H1"}; String[][] expected = new String[][]{actual, {"A1 C1 E1 F1 J1", "A1 C1 E1 F1 K1", "A1 B1 G1 H1"}};

答案 4 :(得分:0)

collection.IsIn在你的上下文中的问题是你的列表中的元素是一个数组,它将使用Array#equals来比较每个元素。

更具体地说

// It will print false, because Array.equals check the reference 
// of objects, not the content
System.out.println(actual.equals(new String[]{"A1 C1 E1 F1 J1", "A1 C1 E1 F1 K1", "A1 B1 G1 H1"}));

所以我建议创建一个使用java中的Arrays.equals的自定义匹配器。它会为您比较数组的内容。像下面的代码:

public boolean matches(Object item) {
    final String[] actualStringArray = (String [])item;

    List<String[]> listOfStringArrays = Arrays.asList(expectedStringMatrix);

    for (String[] stringArray : listOfStringArrays) {
        // Arrays.equals to compare the contents of two array!
        if (Arrays.equals(stringArray, actualStringArray)) {
            return true;
        }
    }
    return false;
}