我使用Spock框架测试我的应用程序,测试是用Groovy编写的。
作为一些方法评估的结果,我有一个对象列表。我想测试这个列表是否与我期望的列表相同。我已经编写了以下代码:
def expectedResults = [ ... ] //the list I expect to see
def isEqual = true;
when:
def realResults = getRealResultsMethod() //get real results in a list here
expectedResults.each {isEqual &= realResults.contains(it)}
then:
isEqual
0 * errorHandler.handleError(_) //by the way assert that my errorHandler is never called
这是我第一次使用Groovy,所以我可能错过了什么?
PS
让我困惑的是Groovy和Spock中的“equals”运算符。给定Java ArrayList或Java数组,equals运算符只是恒等运算符:等于==。在Groovy中,据我所知,默认的equals运算符实际上是equals(形式如下:http://groovy.codehaus.org/Differences+from+Java)。但是什么是Groovy List或Set的“equals”?
更新
更准确地说。我想知道这两个列表是否有相同的对象,两个列表都没有额外的对象,顺序无关紧要。举例来说:
list=[1,5,8]
list1=[5,1,8]
list2=[1,5,8,9]
println(list == list1) //should be equal, if we use == not equal
println(list == list2) //should not be equal, if we use == not equal
5条答案
按热度按时间az31mfrm1#
只要做:
或者,如果你不关心顺序(这违反了List的约定,但你可以这样做),你可以这样做:
或者把它们转换成集合什么的
wswtfjt72#
如果您只需要检查两个列表是否有相同的元素,您可以尝试:
但是如果你需要检查两个列表是否 * 相等 *,你只需要(如@tim_yates的响应):
请记住,两个列表只有在它们具有相同顺序的相同元素时才相等。
y4ekin9u3#
您正在寻找的语义数据结构通常被称为“包”。在包中,就像在集合中一样,元素的顺序并不重要。但是,在包中,就像在列表中一样,允许重复元素。因此,袋相等包括具有相同数量的相同元素,尽管不一定在相同的顺序中。因此,看起来您正在寻找的是一种将“bag”语义应用于列表的方法。最简单的方法是复制其中一个袋子,并从副本中删除另一个袋子的元素,直到:
类似于下面所示的
equals()
实现:或者,如果您根本不关心原始列表顺序,则可以将包表示为一个Map。bag元素值是Map键,每个bag元素的出现次数是Map值。在这一点上,平等只是Map平等。
就像这样:
在任何情况下,如果你只需要检查一次或两次顺序中立的列表等价性,这都是严重的矫枉过正,但是如果经常需要bag语义,那么用这两种方式之一定义一个Bag类可能是一个好主意。
正如其他地方所指出的,在这个特定的情况下,
a.sort() == b.sort()
是一个足够的权宜之计,可以代替完整的包语义。然而,并不是所有可能放在一个列表中的对象都是可相互排序的,即使使用最复杂的比较器闭包也是如此。但是,它们都有hashCode()
和equals()
,这是所示的两个包实现所需的全部内容。此外,
List.sort()
具有 O(n log n) 算法复杂度,而所有显示的包操作都是 O(n) 复杂度。对于这些小名单不值得担心,但对于大名单来说,这是一个更大的问题。nfs0ujit4#
自从Spock 2.1以来,内置了一个比其他答案中提到的更好的选项:
=~
和==~
运算符。查看更多文档==~
完全符合您的要求:两个列表只有当它们包含相同数量的相等对象时才相等,忽略顺序。在您的案例中:
ubof19bj5#