We should always test that methods should return a response within a limited time frame. For this JUnit 5 provides us assertTimeout
and assertTimeoutPreemptively
. Both make sure the execution should be finished before the given time or else the test will fail, but there is a slight difference between the way of execution and failing test case in both asserts.
Assert Timeout
assertTimeout
make sure that the supplier completes within the given time limit or else mark the test case as a failure.
package com.example.junit5.sujan;
import java.util.concurrent.TimeUnit;
public class AppleCalculator {
public String getTimeout() throws InterruptedException {
TimeUnit.SECONDS.sleep(10);
return "apple";
}
}
package com.example.junit5.sujan;
import org.junit.jupiter.api.Test;
import java.time.Duration;
import java.util.function.Supplier;
import static org.junit.jupiter.api.Assertions.assertTimeout;
public class AppleCalculatorTest {
@Test
void assertTimeoutTest() {
AppleCalculator appleCalculator = new AppleCalculator();
assertTimeout(Duration.ofSeconds(5), () -> appleCalculator.getTimeout());
assertTimeout(Duration.ofSeconds(5), () -> appleCalculator.getTimeout(), "oops time out");
Supplier<String> messageSupplier = () -> "oops time out";
assertTimeout(Duration.ofSeconds(5), () -> appleCalculator.getTimeout(), messageSupplier);
}
}
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation('org.junit.jupiter:junit-jupiter:5.6.2')
}
With assertTimeout
The test case and the supplier method both will run in the same thread.
package com.example.junit5.sujan;
import java.util.concurrent.TimeUnit;
public class AppleCalculator {
public String getTimeout() throws InterruptedException {
System.out.println("AppleCalculator.getTimeout ThreadId:- " + Thread.currentThread().getId() + " ThreadName:- " + Thread.currentThread().getName());
TimeUnit.SECONDS.sleep(1);
return "apple";
}
}
package com.example.junit5.sujan;
import org.junit.jupiter.api.Test;
import java.time.Duration;
import java.util.function.Supplier;
import static org.junit.jupiter.api.Assertions.assertTimeout;
public class AppleCalculatorTest {
@Test
void assertTimeoutTest() {
System.out.println("AppleCalculatorTest.assertTimeoutTest " + Thread.currentThread().getId() + " ThreadName:- " + Thread.currentThread().getName());
AppleCalculator appleCalculator = new AppleCalculator();
assertTimeout(Duration.ofSeconds(5), () -> appleCalculator.getTimeout());
assertTimeout(Duration.ofSeconds(5), () -> appleCalculator.getTimeout(), "oops time out");
Supplier<String> messageSupplier = () -> "oops time out";
assertTimeout(Duration.ofSeconds(5), () -> appleCalculator.getTimeout(), messageSupplier);
}
}
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation('org.junit.jupiter:junit-jupiter:5.6.2')
}
The main difference between assertTimeout
and assertTimeoutPreemptively
is that assertTimeout
if supplier methods exceed the given time limit, it will still not kill the execution of the method and let it finish first then fail the test case whereas assertTimeoutPreemptively
will kill the execution that instant only and fail the test case.
package com.example.junit5.sujan;
import java.util.concurrent.TimeUnit;
public class AppleCalculator {
public String getTimeout() throws InterruptedException {
for (int value = 0; value < 10; value++) {
System.out.println("AppleCalculator.getTimeout iteration:- " + value);
TimeUnit.SECONDS.sleep(1);
}
return "apple";
}
}
package com.example.junit5.sujan;
import org.junit.jupiter.api.Test;
import java.time.Duration;
import java.util.function.Supplier;
import static org.junit.jupiter.api.Assertions.assertTimeout;
public class AppleCalculatorTest {
@Test
void assertTimeoutTest() {
AppleCalculator appleCalculator = new AppleCalculator();
assertTimeout(Duration.ofSeconds(5), () -> appleCalculator.getTimeout());
assertTimeout(Duration.ofSeconds(5), () -> appleCalculator.getTimeout(), "oops time out");
Supplier<String> messageSupplier = () -> "oops time out";
assertTimeout(Duration.ofSeconds(5), () -> appleCalculator.getTimeout(), messageSupplier);
}
}
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation('org.junit.jupiter:junit-jupiter:5.6.2')
}
Assert Timeout
assertTimeout
make sure that the supplier completes within the given time limit or else mark the test case as a failure.
package com.example.junit5.sujan;
import java.util.concurrent.TimeUnit;
public class AppleCalculator {
public String getTimeout() throws InterruptedException {
TimeUnit.SECONDS.sleep(10);
return "apple";
}
}
package com.example.junit5.sujan;
import org.junit.jupiter.api.Test;
import java.time.Duration;
import java.util.function.Supplier;
import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
public class AppleCalculatorTest {
@Test
void assertTimeoutPreemptivelyTest() {
AppleCalculator appleCalculator = new AppleCalculator();
assertTimeoutPreemptively(Duration.ofSeconds(5), () -> appleCalculator.getTimeout());
assertTimeoutPreemptively(Duration.ofSeconds(5), () -> appleCalculator.getTimeout(), "oops time out");
Supplier<String> messageSupplier = () -> "oops time out";
assertTimeoutPreemptively(Duration.ofSeconds(5), () -> appleCalculator.getTimeout(), messageSupplier);
}
}
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation('org.junit.jupiter:junit-jupiter:5.6.2')
}
With assertTimeoutPreemptively
The test case and the supplier method both will run in the different thread.
package com.example.junit5.sujan;
import java.util.concurrent.TimeUnit;
public class AppleCalculator {
public String getTimeout() throws InterruptedException {
System.out.println("AppleCalculator.getTimeout ThreadId:- " + Thread.currentThread().getId() + " ThreadName:- " + Thread.currentThread().getName());
TimeUnit.SECONDS.sleep(10);
return "apple";
}
}
package com.example.junit5.sujan;
import org.junit.jupiter.api.Test;
import java.time.Duration;
import java.util.function.Supplier;
import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
public class AppleCalculatorTest {
@Test
void assertTimeoutPreemptivelyTest() {
System.out.println("AppleCalculatorTest.assertTimeoutPreemptivelyTest ThreadId:- " + Thread.currentThread().getId() + " ThreadName:- " + Thread.currentThread().getName());
AppleCalculator appleCalculator = new AppleCalculator();
assertTimeoutPreemptively(Duration.ofSeconds(5), () -> appleCalculator.getTimeout());
assertTimeoutPreemptively(Duration.ofSeconds(5), () -> appleCalculator.getTimeout(), "oops time out");
Supplier<String> messageSupplier = () -> "oops time out";
assertTimeoutPreemptively(Duration.ofSeconds(5), () -> appleCalculator.getTimeout(), messageSupplier);
}
}
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation('org.junit.jupiter:junit-jupiter:5.6.2')
}
assertTimeoutPreemptively
will kill the execution that instant only and fail the test case if supplier methods exceed the given time limit.
package com.example.junit5.sujan;
import java.util.concurrent.TimeUnit;
public class AppleCalculator {
public String getTimeout() throws InterruptedException {
for (int value = 0; value < 10; value++) {
System.out.println("AppleCalculator.getTimeout iteration:- " + value);
TimeUnit.SECONDS.sleep(1);
}
return "apple";
}
}
package com.example.junit5.sujan;
import org.junit.jupiter.api.Test;
import java.time.Duration;
import java.util.function.Supplier;
import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
public class AppleCalculatorTest {
@Test
void assertTimeoutPreemptivelyTest() {
AppleCalculator appleCalculator = new AppleCalculator();
assertTimeoutPreemptively(Duration.ofSeconds(5), () -> appleCalculator.getTimeout());
assertTimeoutPreemptively(Duration.ofSeconds(5), () -> appleCalculator.getTimeout(), "oops time out");
Supplier<String> messageSupplier = () -> "oops time out";
assertTimeoutPreemptively(Duration.ofSeconds(5), () -> appleCalculator.getTimeout(), messageSupplier);
}
}
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation('org.junit.jupiter:junit-jupiter:5.6.2')
}