Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to freeze System.currentTimeMillis() for testing

Tags:

java

testing

For some testing purposes I would like to predict exactly what System.currentTimeMillis() will return. Is there any way in which I can freeze or manually set what will return when System.currentTimeMillis() is called?

like image 859
user22098 Avatar asked Jul 01 '13 06:07

user22098


1 Answers

I would strongly suggest that you avoid using System.currentTimeMillis (and new Date() etc) in your general code.

Instead, create a Clock interface representing "a service to give you the current time" and then create one implementation which does use System.currentTimeMillis or whatever, and a fake implementation that you can control explicitly.

Use dependency injection to make an instance of this service available to code which needs it. In production, use the System.currentTimeMillis version, and in testing use your fake.

This gives you the ability not just to stop time, but to set it to whatever you want - so you can have static test data which you know will never expire, and you can easily test tricky things around boundaries etc. I've used this approach very successfully in many projects, to the extent that in my Noda Time project it's the way of getting at "the current time".

Note that if you're doing any serious amount of time work in Java, I'd recommend using Joda Time, and making your Clock interface return an Instant:

public interface Clock {
    Instant now();
}
like image 52
Jon Skeet Avatar answered Nov 01 '22 01:11

Jon Skeet