I\'m writing some code that does date and time calculations against the current time. In Joda time, this is accessed through a (Java) constructor, as it is an immutable obje
you could just use good old-fashioned OO principles, e.g.
interface TimeService {
DateTime getCurrentTime()
// other time-related methods
}
class JodaTimeService implements TimeService {
DateTime getCurrentTime() {
new DateTime()
}
}
class MockTimeService implements TimeService {
DateTime getCurrentTime() {
// return a fixed point in time
}
}
Your code should get a reference to an implementation of TimeService
via dependency injection. In resources.groovy
use the MockTimeService
only when running the tests
import grails.util.Environment
beans = {
if (Environment.current == Environment.TEST) {
timeService(MockTimeService)
} else {
timeService(JodaTimeService)
}
}
I know this as already been accepted, but with Joda-time you can freeze and set it to be whatever you like. So you can freeze time, advance time, go backwards in time. Provided you're using Joda consistently, your objects will get "now" as whatever time you've set that to be.
// Stop time (and set a particular point in time):
DateTimeUtils.setCurrentMillisFixed(whenever);
// Advance time by the offset:
DateTimeUtils.setCurrentMillisOffset(offsetFromCurrent);
// Restore time (you could do this in an @After method)
DateTimeUtils.setCurrentMillisSystem();
We ended up creating dateService
with now()
method. In unit tests we mock it with
domainInstance.dateService = [ now: { currentTime } ] as DateService
where currentTime
is a unit test class field. This imposes everybody's dependency on dateService
(our only nearly-global dependency), and for src
classes one has to pass it by hand.
Unit tests, OTOH, look pretty clear with it.