问题描述
我有一个函数,可以将以毫秒为单位的时间转换为LocalDate
对象:
def convertToLocalDateTimeViaInstant(datetoConvert: java.util.Date): java.time.LocalDate =
datetoConvert.toInstant.atZone(ZoneId.systemDefault).toLocalDate
我对此功能进行了单元测试,如下所示:
"convertToLocalDateTimeViaInstant" should {
"return the correct LocalDate instance" in new SAMLServiceTestEnv() {
val timeInMillis: Long = 1349333576093L // Date is Thu Oct 04 2012 06:52:56 UTC in millis
val someDate = new Date(timeInMillis)
val resultDate: LocalDate = samlServiceImpl.convertToLocalDateTimeViaInstant(someDate)
resultDate.getYear mustEqual 2012
resultDate.getMonth mustEqual java.time.Month.OCTOBER
resultDate.getDayOfMonth mustEqual 4
}
}
当我单独运行此测试或整个文件时,此测试将做出正确的断言。值1349333576093L
对应于Thu Oct 04 2012 06:52:56
UTC和Wed Oct 03 2012 23:52:56
PST(旧金山时间)。
但是,当我在项目中运行所有单元测试时,发现该测试失败。 resultDate.getDayOfMonth mustEqual 4
断言未能说明4 is not equal to 3
。我很惊讶地看到这一点,因为该函数在单独运行时清楚地考虑了UTC时间,但在一起运行时却以某种方式遵守本地时间?我在这里做什么错了?
解决方法
标准做法是不要直接使用LocalDate.now()
。都一样您有一些Clock
或Timer
正在为您提供当前时间,如果您需要在时间很重要的地方进行任何测试-您只需对当前时间提供者存根即可将时间固定为某个值。并且您完全从测试中删除了时间依赖性。设计可能会破坏其他任何方法,无论您希望如何“实用”。
事实上,Clock
是JDK 8中的内置对象:https://docs.oracle.com/javase/8/docs/api/java/time/Clock.html,因此您甚至不必引入新的依赖关系。