Mock a Clock
Functions are great for testability
/**
* Time Service
*/
public interface TimeService
{
/**
* Returns the current in msec since 1970-01-01 in UTC
*
* @return current time in msec since 1970-01-01
*/
public long currentTime();
}
That is not your functional interface.
How a solution might look like
public class TimeService
{
// hold our source
private final LongSupplier source;
/**
* A standard system time based service
*/
public TimeService()
{
this.source = System::currentTimeMillis;
}
/**
* Inject any time of source that supplies longs
* @param source a long supplier
*/
public TimeService(final LongSupplier source)
{
this.source = source;
}
/**
* Returns the time based on the chosen supplier
* @return the time as long
*/
public long currentTime()
{
return source.getAsLong();
}
}
public class TimeMock
{
@Test
public void standardTime()
{
final TimeService ts = new TimeService();
Assert.assertTrue(System.currentTimeMillis() >= ts.currentTime());
}
@Test
public void staticTime()
{
final TimeService ts = new TimeService(() -> 412345678);
Assert.assertTrue(412345678 == ts.currentTime());
}
@Test
public void timeList()
{
final Deque<Long> series = new ArrayDeque<>();
series.addAll(Arrays.asList(4L, 5L, 6L));
final TimeService ts = new TimeService(series::pop);
Assert.assertTrue(4 == ts.currentTime());
Assert.assertTrue(5 == ts.currentTime());
Assert.assertTrue(6 == ts.currentTime());
}
}
Of course you can add a singleton concept if you like or a factory to get a new time service from.