比较对象的所有字段

时间:2017-04-28 12:07:30

标签: groovy spock

在我们的集成测试中,我们不想将Rest控制器返回的Object的每个字段与测试中构造的对象进行比较。

此示例说明了问题:

class RestIntegrationTest extends Specification {

    def "Should return contracts"() {
        when:
        def actual = callRestController()

        then:
        // compare all fields of actual with "contract"
        actual == new Contract(
                number: "123",
                signDate: "2017-04-01",
                address: new Address(
                        name: "Foobar",
                        street: "Foostreet",
                        city: "Frankfurt",
                        zip: "60486"
                ),
                persons: [new Person(name: "Christian")]
        )
    }

    def callRestController() {
        return new Contract(
                number: "123",
                signDate: "2017-04-01",
                address: new Address(
                        name: "Foobar",
                        street: "Wrong Street",
                        city: "Frankfurt",
                        zip: "60486"
                ),
                persons: [new Person(name: "Frank")]
        )
    }

    static class Contract {
        String number
        String signDate
        Address address
        Person[] persons
    }

    static class Address {
        String name
        String street
        String city
        String zip
    }

    static class Person {
        String name
    }

}

作为输出,我们喜欢这样的东西:

address.street "Wrong Street" != "Foostreet"
persons[0].name "Christian" != "Frank"

将断言分解为多个" =="线条将导致正确的输出,但这不会很方便,因为有些对象非常庞大。

3 个答案:

答案 0 :(得分:1)

你可以尝试groovy的R-lang#Indexing

import groovy.transform.EqualsAndHashCode

@EqualsAndHashCode
static class Address {
    String name
    String street
    String city
    String zip
}

答案 1 :(得分:1)

您可以使用单位assertReflectionEquals http://unitils.sourceforge.net/tutorial-reflectionassert.html

答案 2 :(得分:0)

它并不全面,但可能足以满足您的需求:

def compareFields( obj1, obj2, propName = null ) {
    obj1.properties.each {
        if ( it.value instanceof Object[] ) {
            def obj2Len = obj2."${it.key}".length

            it.value.eachWithIndex { collObj, idx ->
                if ( idx + 1 <= obj2Len )
                    compareFields( collObj, obj2."${it.key}"[idx], "${it.key}[${idx}]" )
            }
        }

        if ( !it.value.class.getCanonicalName().contains( 'java' ) ) {
            compareFields( it.value, obj2."${it.key}", it.key )
        }

        if ( it.value.class.getCanonicalName().contains( 'java' ) &&
                it.key != 'class' &&
                    it.value <=> obj2."${it.key}") {
            println "${propName ? "$propName." : ''}${it.key}: '${it.value}' != '" + obj2."${it.key}" + "'"
        }
    }
}