使用spock数据表填充对象

时间:2014-10-02 07:57:59

标签: java groovy spock

我第一次使用Spock。由于我们使用的是复杂的域模型,因此可以使用一种机制,这种机制允许我根据spock表给出的数据创建完整的对象。我不想每次都给出所有值,我只想设置datable中定义的值。所以应该在某处定义默认值。

是的,我知道我可以自己写,但也许有一个开箱即用的解决方案。

实施例

class A {
   String name
   int age
}

spock table

id | givenA                     | ...
1  | [name: "Michael"]          | ...
2  | [name: "Thomas", age: 45 ] | ...
  1. => A.name =" Michael",A.age =在某处定义默认值
  2. => A.name =" Thomas" A.age = 45(因为我覆盖了默认值)

4 个答案:

答案 0 :(得分:11)

在我拥有的每个项目中,我创造了我所称的' UnitTestUtils'此类主要包含辅助方法,这些方法使用默认值创建域对象,并允许覆盖这些值。例如:

    Person createTestPerson(Map overrides = [:]){
        Person p = new Person(name: "Jim Bob", age: 45)
        overrides.each { String key, value ->
            if(p.hasProperty(key)){
                p.setProperty(key, value)
            } else {
                println "Error: Trying to add property that doesn't exist"
            }
        }
        return p
    }

然后,您可以通过以与您已经完成相同的方式创建地图,在课堂上使用此方法。

    void "my test"(){
        given:
            Person person
        when:
            person = UnitTestUtils.createTestPerson(givenA)
        then:
            person.name == expected.name
            person.age == expected.age
        where:
          id| givenA        | expected
          1 | [name: "Joe"] | [name: "Joe", age: 45]
          2 | [age: 5]      | [name: "Jim Bob", age: 5]
    }

它不是内置的Spock功能,但它应该很好地为您指定的用例提供。

答案 1 :(得分:1)

基本上没有你正在寻找的机制。如果您需要为某些对象/字段提供默认值您需要自己动手并且没有任何奇怪,不好或不寻常的事情。请记住,测试代码的质量与生产代码一样重要,创建一些仅用于测试的帮助代码并不是一个坏习惯(当然,此代码仅存在于测试层次结构)。

在这种特殊情况下,而不是创建A类您可以使用Map.withDefault构造,但使用专用类的IMO要好得多。

答案 2 :(得分:1)

为什么不为此使用构建器模式?您可以提供一种方法,该方法将创建具有默认值的具体A对象,例如。

A.builder()
     .withDefaults(HereAreDefaultValues.class)
     .withName('Michael')
     .build()

此示例使用单独的类来存储默认值,它应该在构建阶段复制所有这些属性。您也可以使用地图。

在这种情况下,任何稍后将阅读您的测试的人都将能够检查默认值是什么,并且如果在这些默认值发生更改时测试失败,则不会感到惊讶。您应该避免隐藏队友(甚至是您自己)的默认值等细节,因为这会使您的测试难以维护。 我知道,Builder示例更详细,但它作为软件的工件肯定更有用。

答案 3 :(得分:0)

不确定您究竟在寻找什么,但您可以写[name: "Thomas", age: 45]而不是new A(name: Thomas, age: 45)。如果你想重复使用灯具,你可以这样做:

where:
[id, givenA] << staticUtilityMethodThatReturnsCollectionOfTwoElementCollections()

您还可以创建一个小API(或使用Groovy的内置集合操作)来修改默认值。