检查Groovy中Comparable对象列表的相等性

时间:2017-11-16 15:36:55

标签: groovy

我正在使用Spock框架编写测试,并且在测试列表相等时发现了一个奇怪的bavior。

当我比较像

这样的两个列表时
sourceList == targetList

并且这些列表包含相同类型的Comparable对象,使用compareTo方法而不是equals来测试这些对象是否相等。

在这些列表上测试相等性时,有什么简单的方法可以强制Groovy使用equals吗?

这是一个简单的测试规范,其中测试应该失败,但事实并非如此。

class Test extends Specification {

def "list test"() {
    when:
        def listA = [[index: 1, text: "1"] as Bean, [index: 2, text: "2"] as Bean]
        def listB = [[index: 1, text: "1"] as Bean, [index: 2, text: "3"] as Bean]

    then:
        listA == listB
}

class Bean implements Comparable<Bean> {

    int index
    String text

    @Override
    public int compareTo(Bean o) {
        return index.compareTo(o.index);
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + index;
        result = prime * result + ((text == null) ? 0 : text.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof Bean)) {
            return false;
        }
        Bean other = (Bean) obj;
        if (index != other.index) {
            return false;
        }
        if (text == null) {
            if (other.text != null) {
                return false;
            }
        } else if (!text.equals(other.text)) {
            return false;
        }
        return true;
    }

}

}

1 个答案:

答案 0 :(得分:0)

要求简单方法是主观的。这个答案的关键是,在Groovy中,is()方法将check object equality

ArrayList上考虑这个新方法。如果合适,它会将两个列表压缩在一起,并在每对项目上调用is()

ArrayList.metaClass.myCompare = { listB ->
    def result = false
    def listA = delegate
    if (listB && listA.size() == listB.size()) {
        def zipped = [listA, listB].transpose()
        result = zipped.inject(true){ ok, pair ->
            ok && pair[0].is(pair[1])
        }
    }
    result
}

然后:

def beanA = new Bean(index: 1, text: 'a')
def beanA1 = new Bean(index: 1, text: 'a')
def beanB = new Bean(index: 2, text: 'b')

assert [beanA, beanB].myCompare([beanA, beanB])
assert ! [beanA, beanB].myCompare([beanA1, beanB])
assert ! [beanA, beanB].myCompare([beanA])
assert ! [beanA, beanB].myCompare(null)
assert ! [beanA, beanB].myCompare([])