There are two problems with using (real) time in test cases:
- It is never really deterministic. Especially when you are looking for high precision, testcases will succeed 95% of the time. But sometimes they fail, these are the hardest types of failure to debug. Note that when using
Thread.sleep()
with in a multithreaded test case this is even more difficult.
- Test cases with sleeps take long to run, after a while this will make running your full testset cumbersome.
If you must, your way is acceptable. But there are other options:
Don't use a real clock. Instead use a fake (mocked/stubbed) clock that you can control from your testcase:
@Test(expected = IllegalStateException.class)
public void testCallAfterTimeout() {
MyObject o= new MyObject();
// Example function that you could make
advanceClock(1000, TimeUnit.MILLISECONDS)
o.call();
}
In your object you have to inject a clock. MyObject
could look like this:
class MyObject
{
public MyObject()
{
this(new Clock());
}
// Protected so only the test case can access it
protected MyObject(Clock clock)
{
// Save clock as local variable, store creation time etc.
}
}
In Java 8 a mechanism for this is provided, see for instance LocalDate.now()
. But you can also implement your own quiet easily.