Junit 5 Assert Timeouts

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')
}

follow us on