Thread.sleep in a JUnit test case

I am writing a test case to test the behavior of an object.

When an instance of an object is created, it should only allow the say say say call () method to be called if it was called within 500 ms, otherwise it should throw an exception.

I developed a Junit test case as follows:

@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 this is good practice, or should I follow a different approach?

Many thanks

+4
source share
2 answers

In test cases, there are two problems using (real) time:

  • It is never determined. Especially if you are looking for high accuracy, test cameras will be successful in 95% of cases. But sometimes they fail; these are the most complex types of debugging. Note that using Thread.sleep() in a multi-threaded test case is even more complicated.
  • Tests with dreams take a lot of time, and after a while this will make your complete test suite cumbersome.

If you want your path to be acceptable. But there are other options:

Do not use a real watch. Instead, use a fake (mocked / stubbed) clock, which you can control from your test file:

 @Test(expected = IllegalStateException.class) public void testCallAfterTimeout() { MyObject o= new MyObject(); // Example function that you could make advanceClock(1000, TimeUnit.MILLISECONDS) o.call(); } 

You must enter the hours in your facility. MyObject might 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. } } 

Java 8 provides a mechanism for this; see, for example, LocalDate.now() . But you can also easily realize your own silence. Please note that the Java 8 clock provides additional mechanisms to automatically increase the time you use.

+7
source

No matter what this is and what you ask for trouble ....

What if you decide that a timeout should happen in 60 minutes, will you wait one hour for your test? The timeout should be a parameter of your MyObject, so you can set it to a small value for testing (or even 0 to force allwas timeout when testing).

Secondly, if you really want to have time-tested functions, the time and timeout should be handled separately from your main logic (MyObject class). For example, you might have a Timekeeper class with mehtod canCallMethod (), which is called by the MyObject class (and is set to build it). Thus, in your test, you initialize your MyObject class with your Timekeeper implementation, which returns true or false, and make sure your MyObject class behaves as expected. MyObject may have a default constructor that always uses a "real" timeout, so the outside world is not a force for working with Timekeeper's internal functions.

+1
source

All Articles