Spock 中的数据驱动测试

Data driven tests in Spock

我正在将一些 JUnit 测试重写到 Spock 中以利用数据驱动的测试风格。

我正在为如何提供动态验证而苦恼。

这是我目前的情况:

def "domestic rules"(from, to, oneWay, check) {

    expect:
    String mealResponse = getMealResponse(new BookingOptions.BookingOptionsBuilder().setFrom(from).setTo(to).setOneWay(oneWay).build());
    check(mealResponse)

    where:
    from  | to    | oneWay || check
    'MNL' | 'PEK' | true   || assertNoMeals()
}

def assertNoMeals = {
    assert JsonAssert.with(it)
            .assertThat('$.links', hasSize(1))
            .assertThat('$.links[0].rel', is("http://localhost:9001/api/docs/rels/ink/meal-allocations"))
            .assertThat('$.links[0].uri', startsWith("http://localhost:9001/api/tenants/acme/meals/allocations/"));
}

不幸的是,我在第一行数据的行得到一个 NullPointerException。

我想那是因为闭包在那个时候 运行,而不是刚刚声明。

有没有更好的方法?

def "domestic rules"() {

  when: 'get meals using certain parameters'
  String mealResponse = getMealResponse(new BookingOptions.BookingOptionsBuilder().setFrom(from).setTo(to).setOneWay(oneWay).build())

  then: 'the json response should contain some contents (improve the message here!)'
  JsonAssert.with(mealResponse)
        .assertThat('$.links', hasSize(1))
        .assertThat('$.links[0].rel', is(somethingToUseInAssertions))


  where:
  from  | to    | oneWay || somethingToUseInAssertions
  'MNL' | 'PEK' | true   || 'just some example'
}

以上应该可以帮助您走上正轨。请注意,您应该只在示例中有一些值。如果您需要断言中的一些逻辑,请使用一个值来指示需要进行哪种断言...但是使用闭包作为示例是一个非常糟糕的主意。

改变

def "domestic rules"(from, to, oneWay, check) {

@Unroll
def "domestic rules from #from to #to one way #oneWay"() {

如果您真的想让您的测试难以维护并继续在您的示例中使用闭包 "values",那么请执行以下操作:

def "domestic rules"() {

  when:
  String mealResponse = getMealResponse(new BookingOptions.BookingOptionsBuilder().setFrom(from).setTo(to).setOneWay(oneWay).build())

  then:
  check(mealResponse)

  where:
  from  | to    | oneWay || check
  'MNL' | 'PEK' | true   || this.&assertNoMeals 
}

boolean assertNoMeals(mealResponse) {
  assert JsonAssert.with(mealResponse)
        .assertThat('$.links', hasSize(1))
        .assertThat('$.links[0].rel',  is("http://localhost:9001/api/docs/rels/ink/meal-allocations"))
        .assertThat('$.links[0].uri',   startsWith("http://localhost:9001/api/tenants/acme/meals/allocations/"))
  return true // pass!
}

我建议你先把Groovy和Spock都学一遍再写比较合理的东西。这并不难,但至少需要几个小时!