Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread.sleep in JUnit test case

Tags:

java

junit

I'm writing a test case to test an object behaviour.

When the object is instantiated it must allow the call of a method let say call() only if it has been called within 500 ms, otherwise it must throw an exception.

I designed the Junit test case like this:

@Test(expected = IllegalStateException.class)
public void testCallAfterTimeout() {
    MyObject o= new MyObject();
    //To ensure the timeout is occurred
    Thread.sleep(1000);
    o.call();
}

Do you think is a good practice or I should follow another approach?

Many thanks

like image 399
Piero Nadello Avatar asked Feb 24 '15 12:02

Piero Nadello


1 Answers

There are two problems with using (real) time in test cases:

  1. 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.
  2. 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.

like image 188
Thirler Avatar answered Sep 23 '22 09:09

Thirler