Unit-testing – How to automatically test a time check

timeunit testing

Say you have a property startTime. Then you have a method doSomething:

doSomething() {
   //...stuff
   startTime = System.currentTimeMillis();
   //... more stuff
}

How do you test that startTime was assigned correctly? You can't test against an absolute timestamp – it'll likely change between assignment and test. Maybe use a range?

Best Answer

One simple way is to pass in the time from outside the method:

doSomething(long currentTime) {
   //...stuff
   startTime = currentTime;
   //... more stuff
}

Your production code that calls the method can pass in the real value for System.currentTimeMillis(), whereas your unit test(s) can pass in a specific known value.

Of course, this isn't quite the same as your original. Another possibility that is a little more complex but should mimic the behaviour of your of your original more closely:

doSomething(ITimeGetter timeGetter) {
   //...stuff
   startTime = timeGetter.GetCurrentTime;
   //... more stuff
}

Define the interface:

interface ITimeGetter
{
   long GetCurrentTime();
}

Two implementations, one for the production code:

class RealTimeGetter implements ITimeGetter
{
  long GetCurrentTime()
  {
      return System.currentTimeMillis();
  }
}

One for the unit tests:

class TimeGetterForTests implements ITimeGetter
{
  long GetCurrentTime()
  {
     // return a known value.
  }
}

Instantiate an ITimeGetter appropriate to your scenario and pass it in to the method you want to test.