Asserting timeouts

To assess timeouts in JUnit 5 tests, Jupiter provides two assertions: assertTimeout and assertTimeoutPreemptively. On the one hand, assertTimeout, allows us to verify the timeout of a given operation. In this assertion, the expected time is defined using the class Duration of the standard Java package java.time.

We are going to see several running examples to clarify the use of this assertion method. In the following class, we find two tests using assertTimeout. The first test is designed to be succeeded, due to the fact that we are expecting that a given operation takes less than 2 minutes, and we are doing nothing there. On the other side, the second test will fail, since we are expecting that a given operation takes a maximum of 10 milliseconds, and we are forcing it to last 100 milliseconds.

package io.github.bonigarcia;

import static java.time.Duration.ofMillis;
import static java.time.Duration.ofMinutes;
import static org.junit.jupiter.api.Assertions.assertTimeout;

import org.junit.jupiter.api.Test;

class TimeoutExceededTest {

@Test
void timeoutNotExceeded() {
assertTimeout(ofMinutes(2), () -> {
// Perform task that takes less than 2 minutes
});
}

@Test
void timeoutExceeded() {
assertTimeout(ofMillis(10), () -> {
Thread.sleep(100);
});
}
}

 When we execute this test, the second test is declared as failed because the timeout has been exceeded in 90 milliseconds:

Console output of assertTimeout first example

Let's see a couple more tests using assertTimeout. In the first test, assertTimeout evaluates a piece of code as a lambda expression in a given timeout, obtaining its result. In the second test, assertTimeout evaluates a method in a given timeout, obtaining its result:

package io.github.bonigarcia;

import static java.time.Duration.ofMinutes;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTimeout;

import org.junit.jupiter.api.Test;

class TimeoutWithResultOrMethodTest {

@Test
void timeoutNotExceededWithResult() {
String actualResult = assertTimeout(ofMinutes(1), () -> {
return "hi there";
});
assertEquals("hi there", actualResult);
}

@Test
void timeoutNotExceededWithMethod() {
String actualGreeting = assertTimeout(ofMinutes(1),
TimeoutWithResultOrMethodTest::greeting);
assertEquals("hello world!", actualGreeting);
}

private static String greeting() {
return "hello world!";
}

}

In both cases, the tests take less time than expected and therefore both of them are succeeded:

Console output of assertTimeout second example

The other Jupiter assertion for timeouts is called assertTimeoutPreemptively. The difference with assertTimeoutPreemptively with respect to assertTimeout is that assertTimeoutPreemptively does not wait until the end of the operation, and the execution is aborted when the expected timeout is exceeded.

In this example, the test will fail since we are simulating an operation which lasts 100 milliseconds, and we have defined a timeout of 10 milliseconds:

package io.github.bonigarcia;

import static java.time.Duration.ofMillis;
import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;

import org.junit.jupiter.api.Test;

class TimeoutWithPreemptiveTerminationTest {

@Test
void timeoutExceededWithPreemptiveTermination() {
assertTimeoutPreemptively(ofMillis(10), () -> {
Thread.sleep(100);
});
}

}

In this example, when the timeout of 10 ms is reached, instantly the test is declared as a failure:

Console output of assertTimeoutPreemptively example
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.22.77.63