2016-06-08 64 views
0

我正在爲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。

我想多數民衆贊成,因爲封閉運行在那一點,而不是剛剛宣佈。

有沒有辦法做得更好?

+0

你應該閱讀[Spock Primer](http://spockframework.github.io/spock/docs/1.0/spock_primer.html)。你在斷言錯誤。 – Renato

回答

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

以上這些應該有助於您走上正確的軌道。請注意,只有在示例中應該有一些值。如果你在斷言中需要一些邏輯,使用一個值來指示需要做什麼樣的斷言......但是使用閉包作爲例子是一個非常糟糕的主意。

+0

我正在尋找一個解決方案,允許我添加更多行並擁有不同的斷言。你的例子被硬編碼爲一行斷言。 – FinalFive

+0

爲每種類型的斷言創建一個測試。這就是你如何做到的。如果每個示例都有完全不同的斷言,則這些示例屬於不同的功能。 – Renato

+0

我正在將您的答案標記爲解決方案,因爲我已決定放棄這種方法,並按照每個斷言集進行一次測試。我認爲數據驅動的風格更適合於一致的投入和產出。 – FinalFive

2

變化

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

@Unroll 
def "domestic rules from #from to #to one way #oneWay"() { 
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, easonable。這並不難,但它至少需要幾個小時!

+0

剛發現你實際上需要讓'assertNoMeals'返回一個布爾值(true)來讓測試通過...... Spock通常識別void方法,但在這種情況下它不能識別方法引用返回void。 – Renato

+0

不知道你爲什麼認爲這是一個壞主意。參數化測試是有用的,我只是有不同的斷言,雖然他們是JSON斷言。 – FinalFive

+0

如果你有不同的斷言,他們可能會在不同的測試中更好 –