I'm developing a component that provides tokens that have a limited lifespan and need not be persisted in case of application restart. Hence, the tokens are only stored in memory. Each token is identified by a key and have an associated time-to-live after which the token expires and can no longer be used.
I halted to think how would you go about testing that the expiration conditions work as planned?
System.currentTimeMillis does not provide a proper way to inject arbitary times to test the boundaries.Calendar, Joda-Time's DateTime, etc) to the appropriate methods does not make sense outside of the testing context as it's not the responsibility of the caller to know what time it is. sleep() or a busy-wait a reasonable and reliable solutionI'm currently leaning towards option 4 but I'd learn about more options as well!
Overly simplified scribbled scenario:
private static final long LIFE_SPAN = 60000;
private Map<T, Long> bestBeforeDates = new HashMap<T, Long>();
public void add(final T key) {
bestBeforeDates.put(key, System.currentTimeMillis() + LIFE_SPAN);
}
public boolean isExpired(final T key) {
// How to make this fail without waiting for x milliseconds
return bestBeforeDates.get(key) < System.currentTimeMillis();
}
Option 3 is the best IMO. Getting the current time is a service like any other, IMO. It's easy to write a Clock interface and then fake it appropriately. If you're using a decent DI framework you don't need another constructor - just bind the a system implementation to the Clock interface and no further changes are required.
I've used this approach in a number of places and never regretted it. Of course, it depends whether you're already using dependency injection elsewhere - if it's the only dependency you'd be injecting, it's more of a pain.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With