2015-11-06 31 views
3

我有一個Spock規範來測試需要java.util.Date的方法。Spock - 用不同的系統默認值重複測試

def "special dates are identified correctly"() { 
    expect: 
     isSpecialDay(Date.parse('yyyy/MM/dd', date)) == special 
    where: 
     date   | special 
     '2010/01/01' | false 
     '2011/01/01' | true 
     '2012/01/01' | true 
     '2013/01/01' | false 
     '2014/01/01' | true 
     // and lots more... 
} 

我想要確保的時區不會使我的方法實現的差異(即2011年1月1日無論是特殊的,如果我在美國東部時間或GMT或無論是)。 有沒有一種方法可以在一次運行中重複執行測試方法,並且每次執行時使用不同的默認時區?

我可以添加第三列到TimeZone的「where」塊,但是額外的維度會使表格太大而不適合我的喜好。

目前,我爲每次測試運行設置一個隨機默認值,但我不喜歡這樣一個事實,即我的測試不可重複,如果發生故障,有問題的TimeZone不會在斷言消息中捕獲。

@Shared TimeZone defaultTz = TimeZone.getDefault() 

def setupSpec() { 
    def tzIds = TimeZone.getAvailableIDs() 
    def randomTzId = tzIds[new Random().nextInt(tzIds.length)] 
    def randomTz = TimeZone.getTimeZone(randomTzId) 
    println "Using TimeZone $randomTz for test spec" 
    TimeZone.setDefault(TimeZone.getTimeZone(randomTzId)); 
} 

def cleanupSpec() { 
    TimeZone.setDefault(defaultTz) 
} 
+0

parse - http://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Date.html - 被覆蓋並接受'TimeZone'參數。我會在數據表中添加一個'tz'列,並在那裏放置隨機時區。這樣做有可能嗎? – Opal

+0

@Opal - 這是可能的,但如果我想要徹底,每個時區我想檢查的表格會增加100行(當前塊的實際位置是100行) – bdkosher

+0

您可以隨機選擇此過程。不要將TŻ添加到表中,而是從例如預定義集合。 – Opal

回答

3

使用JodaTime可以測試相同的使用DateTimeZone.getAvailableIDs()所有可用的時區。這是一個快速和討厭的實施來展示如何做甘蔗。

@Grab(group='joda-time', module='joda-time', version='2.9') 
@Grab(group='org.spockframework', module='spock-core', version='1.0-groovy-2.4') 

import spock.lang.* 
import org.joda.time.DateTime 
import org.joda.time.DateTimeZone 

class TestSpecialDate extends Specification { 

    def "special dates are identified correctly"() { 
     expect: 
     DateTimeZone.availableIDs.each { tz -> 
      // get current moment in default time zone 
      DateTime dt = new DateTime(Date.parse('yyyy/MM/dd', date)) 

      // translate to local date time 
      DateTime dtLocal = dt.withZone(DateTimeZone.forID(tz)) 

      // Get Java Date and assert 
      assert isSpecialDay(dtLocal.toDate()) == special 
     } 

     where: 
     date   || special 
     '2010/01/07' || false 
     '2011/01/01' || true 
     '2012/01/01' || true 
     '2013/11/06' || false 
     '2014/01/01' || true 
    } 

    // Mimic special day implementation 
    static private boolean isSpecialDay(Date date) { 
     // Check if it is the first day of month 
     return date[Calendar.DAY_OF_MONTH] == 1 
    } 
} 
+0

看起來不錯!你可以用'every'來替換'each'並消除assert語句,但是調試可能會更困難。 – Opal

+0

試過了,那裏。 ;) – dmahapatro

+0

*咳嗽*時區的列表,日期列表,'組合'和其中'@Unroll塊的'<<形式列表? (提示) –

5

以下是使用的組合特技我在上面所暗示的一個例子:

@Grab(group='joda-time', module='joda-time', version='2.9') 
@Grab(group='org.spockframework', module='spock-core', version='1.0-groovy-2.4') 

import spock.lang.* 
import org.joda.time.DateTime 
import org.joda.time.DateTimeZone 

class TestSpecialDate extends Specification { 
    @Shared def zoneCombinations = [ 
     DateTimeZone.availableIDs, 
     [[date:'2010/01/07', special:false], [date:'2011/01/01', special:true], [date:'2012/01/01', special:true], 
     [date:'2013/11/06', special:false], [date:'2014/01/01', special:true]]] 
      .combinations { a, b -> [zone:a, date:b.date, special:b.special] } 


    @Unroll 
    def "#date for #zone should be special #special"() { 
     expect: 
     // get current moment in default time zone 
     DateTime dt = new DateTime(Date.parse('yyyy/MM/dd', date)) 

     // translate to local date time 
     DateTime dtLocal = dt.withZone(DateTimeZone.forID(zone)) 

     // Get Java Date and assert 
     isSpecialDay(dtLocal.toDate()) == special 


     where: 
     date << zoneCombinations.date 
     special << zoneCombinations.special 
     zone << zoneCombinations.zone 
    } 

    // Mimic special day implementation 
    static private boolean isSpecialDay(Date date) { 
     // Check if it is the first day of month 
     return date[Calendar.DAY_OF_MONTH] == 1 
    } 
} 

當在常規控制檯執行,運行:

JUnit 4 Runner, Tests: 2915, Failures: 0, Time: 351 

2915測試:-)

+0

Splendid變體:) – dmahapatro