I have a function where I convert time in millis to a LocalDate
object:
def convertToLocalDateTimeViaInstant(dateToConvert: java.util.Date): java.time.LocalDate =
dateToConvert.toInstant.atZone(ZoneId.systemDefault).toLocalDate
And I have a unit test for this function as follows:
"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
}
}
When I run this test just by itself or the whole file, this test makes the correct assertions. The value 1349333576093L
corresponds to Thu Oct 04 2012 06:52:56
UTC and Wed Oct 03 2012 23:52:56
PST (San Francisco time).
However, when I run ALL the unit tests in the project, I observe a failure in this test. The resultDate.getDayOfMonth mustEqual 4
assertion fails stating 4 is not equal to 3
. I'm surprised to see this as the function clearly considers UTC time when run by itself but somehow observes local time when run all together? What am I doing wrong here?
The standard practice is to not use
LocalDate.now()
directly. Like, at all. You have someClock
orTimer
that is providing you with current time, and if you need to do any tests where time is important - you just stub this current time provider to fix time to some value. And you remove time-dependency from tests altogether. Any other approach is broken by design no matter how "pragmatic" you might want to see it.As a matter of the fact
Clock
is a build-in in JDK 8: https://docs.oracle.com/javase/8/docs/api/java/time/Clock.html so you don't even have to introduce a new dependency.