Testing With the Clock Interface
The Clock
interface along with its default implementation DefaultClock
are aimed at making testing classes that require a date easier. Rather than pass around java.util.Date
classes which will return the current date when constructed, you can pass around a factory which allows you to control the date.
For example, the StopWatch
class maintains an internal Date
which it can use to compare with the current time to work out the elapsed time. A straight forward implementation might look like this
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Writing the (rather silly) test below highlights a problem using real time in the class.
1 2 3 4 5 6 7 8 |
|
The test is unlikely to pass!
java.lang.AssertionError:
Expected: is <Duration 100 MILLISECONDS>
got: <Duration 103 MILLISECONDS>
at org.junit.Assert.assertThat(Assert.java:778)
at org.junit.Assert.assertThat(Assert.java:736)
at com.google.code.tempusfugit.temporal.BadStopWatchTest.getElapsedTime(BadStopWatchTest.java:32)
Whereas, if we write the class using a controllable time, we can write a more deterministic test. Here, we create an alternative stop watch implementation and mock the factory using JMock.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
The test becomes clearer
1 2 3 4 5 6 7 8 9 |
|
Movable Clock
You can use the MovableClock
in tests to explicitly move time forward within the context of a test. For example, we can rewrite the test above as follows.
1 2 3 4 5 6 7 8 |
|
Stop Watches
The StopWatch
class allows you to record the length of time taken between starting and stopping the watch. It's used internally with the WaitFor.waitUntil(Timeout timeout, ...)
class.