Spock中的数据驱动测试

时间:2016-06-08 20:07:37

标签: groovy spock

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

我在如何通过动态提供验证方面苦苦挣扎。

这是我到目前为止所拥有的:

;with res as
(
  select 1 as reservation_id, convert(datetime, '2016-07-21 06:30:00.000', 120) as reservation_start, convert(datetime, '2016-07-21 07:30:00.000', 120) as reservation_end
  union all
  select 2, '2016-07-21 07:00:00.000', '2016-07-22 09:00:00.000'
  union all
  select 3, '2016-08-02 08:45:00.000', '2016-08-03 09:45:00.000'
  union all
  select 4, '2016-08-02 03:00:00.000', '2016-08-02 09:00:00.000'
  union all
  select 5, '2016-08-27 02:30:00.000', '2016-08-28 03:30:00.000'
  union all
  select 6, '2016-08-30 09:00:00.000', '2016-08-30 09:00:00.000'
  union all
  select 7, '2016-07-21 07:31:00.000', '2016-07-22 09:00:00.000'
)
/*
select r.*, r2.reservation_id as conflict_id
from res r
left join res r2
on r2.reservation_id != r.reservation_id
and r2.reservation_start < r.reservation_end and r2.reservation_end >= r.reservation_start
*/

select
  r.reservation_id,
  r.reservation_start,
  r.reservation_end,
  stuff((
    select ',' + cast(r2.reservation_id as varchar(10))
    from res r2
    where r2.reservation_id != r.reservation_id
      and r2.reservation_start < r.reservation_end and r2.reservation_end >= r.reservation_start
    order by r2.reservation_id
    for xml path(''), type
    ).value('.', 'varchar(max)'), 1, 1, '['
  ) + ']' as conflict_ids
from res r

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

我猜那是因为闭包是在那个时候运行的,而不是仅仅声明。

有没有办法更好地做到这一点?

3 个答案:

答案 0 :(得分:2)

更改

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

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

答案 1 :(得分:1)

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'
}

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

答案 2 :(得分:0)

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

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。这并不难,但确实需要至少几个小时!