我有一个Spock规范来测试一个带java.util.Date
的方法。
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...
}
我想确保TimeZone对我的方法实现没有影响(即2011年1月1日是特殊的,无论我是在EST还是GMT或其他什么)。 有没有办法可以在一次运行中重复执行测试方法,每次执行时使用不同的默认时区?
我可以在TimeZone的“where”块中添加第三列,但是这个额外的维度会使表格太大而不符合我的喜好。
目前,我在每个测试运行中设置一个随机默认值,但我不喜欢我的测试不可重复这一事实,如果发生故障,则在断言消息中不会捕获有问题的TimeZone。 / p>
@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 :(得分: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
}
}
在groovy控制台中执行时,运行:
JUnit 4 Runner, Tests: 2915, Failures: 0, Time: 351
2915测试: - )
答案 1 :(得分: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
}
}