如何比较 Spock 集合中不同类型对象中的相似字段名称?

How to compare similar field names in different type of objects in collections in Spock?

我有两个不同类型的集合 - 例如。 FruitVegetable.

现在在 spock 中,我通过以下方式之一声明这些集合的内容:

fruits.size() == vegetables.size()
for (int i = 0; i < fruits.size(); i++) {
    assert fruits[i].name == vegetables[i].name
    assert fruits[i].active == vegetables[i].enabled
}

有没有更好的方法来比较这些集合?

您可以利用 Groovy's spread operator 提取值列表并比较这些列表。考虑以下示例:

class Fruit {
    String name
    boolean active
}

class Vegetable {
    String name
    boolean enabled
}

def fruits = [new Fruit(name: 'Apple', active: false), new Fruit(name: 'Tomato', active: true)]
def vegetables = [new Vegetable(name: 'Apple', enabled: false), new Vegetable(name: 'Tomato', enabled: false)]

assert fruits.name == vegetables.name
assert fruits.active == vegetables.enabled

第一个断言通过,因为:

assert ['Apple', 'Tomato'] == ['Apple', 'Tomato']

但是第二个断言失败了,因为:

assert fruits.active == vegetables.enabled
       |      |      |  |          |
       |      |      |  |          [false, false]
       |      |      |  [Vegetable@5b8dfcc1, Vegetable@2f9f7dcf]
       |      |      false
       |      [false, true]
       [Fruit@747ddf94, Fruit@35e2d654]

在这种情况下,您不必比较两个列表是否具有相同的大小以及对象的顺序是否重要。唯一的缺点是您提取到列表的值必须是可比较的 - 否则它将比较对对象的引用。

最后,您的 Spock 测试可能如下所示:

def "comparing fruits and vegetales"() {
    when:
    def fruits = initializeFruits()
    def vegetables = initializeVegetables()

    then:
    fruits.name == vegetables.names

    and:
    fruits.active == vegetables.enabled
}