Use a fake system clock

When testing an application, it's often useful to define a fake system clock in order to exercise code that uses dates.

While it's always possible to change the system clock directly, many view that style as undesirable:

Instead of changing the system clock, it's possible to define a fake system clock just for your application. In production, the fake system clock returns normal time. During testing, the fake system clock is changed to return any time you need for effective test coverage. Of course, your application code will always need to reference the fake system clock, and never the real one, in order for this to work.

Example

The TimeSource interface allows you to define various implementations of a fake system clock:

public interface TimeSource {

  /** Return the system time. */  
  long currentTimeMillis();

} 
This implementation mimics a system clock running one day in advance:
public final class TimeSrc implements TimeSource {

  /** One day in advance of the actual time.*/
  @Override public long currentTimeMillis() {
    return System.currentTimeMillis() + ONE_DAY;
  }
  
  private static final long ONE_DAY = 24*60*60*1000;

} 
Using various TimeSource implementations, you can mimic any desired behavior for a system clock. Possible behaviors include:

For this to work, an application must avoid using the system clock directly, by avoiding methods such as:

Instead, an application must reference only a TimeSource.

According to your needs, you may have to use the fake system clock in some or all of these places:

It's simple to configure the JDK logger to use your fake system clock. A simple custom Formatter can use your TimeSource to alter the time of the LogRecord:

import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;

public final class SimpleFormatterTimeSource extends SimpleFormatter {

  @Override public String format(LogRecord aLogRecord) {
    aLogRecord.setMillis(fTimeSource.currentTimeMillis());
    return super.format(aLogRecord);
  }

  private TimeSource fTimeSource = BuildImpl.forTimeSource();
}
 

See Also :
Use a testing framework (JUnit)
Plugin Factory