2015-11-06 64 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