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 calling these items directly:

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
Would you use this technique?
Yes   No   Undecided   
© 2014 Hirondelle Systems | Source Code | Contact | License | RSS
Individual code snippets can be used under this BSD license - Last updated on September 21, 2013.
Over 2,000,000 unique IPs last year - Built with WEB4J.
- In Memoriam : Bill Dirani -