Assert.assertEquals的奇怪行为

时间:2016-03-18 10:46:07

标签: java junit

根据这里的很多帖子,Assert.assertEquals应该使用深入洞察来比较集合,并且两个相同内容的数组应该相等。

我安装了JUnit 4.12。

致电

List<Integer[]> result, targetResult;
(both are created as ArrayList)
....
Assert.assertEquals("counted small array ", result, targetResult);

,其中result和targetResult具有相同的内容,但测试失败了。

我看过assertEquals是如何完成工作的。为了比较它到达的整数数组:

//----in AbstractList: 
public boolean equals(Object o) {
    if (o == this)
        return true;
    if (!(o instanceof List))
        return false;

    ListIterator<E> e1 = listIterator();
    ListIterator e2 = ((List) o).listIterator();
    while (e1.hasNext() && e2.hasNext()) {
        E o1 = e1.next();
        Object o2 = e2.next();
        if (!(o1==null ? o2==null : o1.equals(o2)))
            return false;
    ...

//and more deep, in Object:
public boolean equals(Object obj) {
    return (this == obj);
}

这意味着它只是比较参考文献。

如何让Assert.assertEquals()正常工作?

2 个答案:

答案 0 :(得分:4)

assertEquals的问题是假设equals(Object)是理智的。不幸的是,Object直接固有的所有数组并没有专门的方法。这意味着您必须调用Arrays.equals(a,b)来比较两个数组,但是如果这些数组在集合中,则无法方便地执行此操作。

注意:我不知道为什么打印[Ljava.lang.Integer@72173fed对于这样的数组来说是一个很好的toString(这是我在我的博客中多次反对的事情)

  

这意味着,它只是比较哈希码。

它不比较hashCode(),它比较引用。 hashCode()不是内存地址,也不能在对象在内存中移动时无法更改。

如果您希望数据结构相同,请使用支持您所期望的等于的集合

List<List<Integer>> result

如果你想要效率int使用4个字节而Integer可以使用20个字节,包括它的参考。

List<int[]> result

public static void assertEqualsArray(List<Int[]> a, List<int[]> b) {
   // compare the list of arrays.
}

答案 1 :(得分:0)

考虑:

Assert.assertArrayEquals(result.toArray(), targetResult.toArray());