Awaitility Java Guide: Complete Tutorial with Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Awaitility for Java: The Complete Guide with Examples

1. What Is Awaitility and Why You Need It

Awaitility is a powerful Java library that provides an expressive DSL (Domain-Specific Language) for writing asynchronous tests. In modern development, we constantly deal with async operations: HTTP requests, database calls, message queues, CompletableFuture, reactive streams, and more. Traditional testing approaches like Thread.sleep() produce brittle, slow, and unreliable tests. Awaitility solves this by letting you declaratively define expectations: "wait, but no longer than 10 seconds, until a condition becomes true, checking every 100 milliseconds."

The library's core value is making async tests stable, readable, and performant. Instead of guessing how long an operation will take, you describe the system's final state. Awaitility handles wait times, polling intervals, and exception handling automatically. This is especially critical when testing microservices, integration scenarios, and distributed systems where execution times can vary widely.

Awaitility integrates with all major testing frameworks (JUnit 4/5, TestNG, Spock) and works in both unit and integration tests. It doesn't impose any specific async approach — it works with callbacks, Futures, reactive streams, Event Bus, and more. The only requirement is the ability to check system state at a given point in time.

2. Installation

Awaitility is distributed through Maven Central. Add it to your project using your preferred dependency manager.

Maven (pom.xml)

<dependency>
    <groupId>org.awaitility</groupId>
    <artifactId>awaitility</artifactId>
    <version>4.2.1</version>
    <scope>test</scope>
</dependency>

Gradle (build.gradle)

testImplementation 'org.awaitility:awaitility:4.2.1'

Gradle Kotlin DSL (build.gradle.kts)

testImplementation("org.awaitility:awaitility:4.2.1")

Check the Latest Version

You can find the latest version on MVNRepository. As of this writing, the latest stable release is 4.2.1 (compatible with Java 8+).

3. Quick Start — Minimal Working Example

Let's look at a simple example: we have a service that updates a value asynchronously. We want to wait until the value equals 5.

import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class QuickStartTest {

    @Test
    public void shouldWaitForAsyncUpdate() {
        // Simulate an async service
        AtomicInteger counter = new AtomicInteger(0);

        // Start a background thread that increments the counter
        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(200); // Simulate work
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                counter.incrementAndGet();
            }
        }).start();

        // Awaitility waits until counter equals 5
        Awaitility.await()
                .atMost(5, TimeUnit.SECONDS)
                .until(() -> counter.get() == 5);

        // Verify the result
        assert counter.get() == 5 : "Counter should be 5";
    }
}

This test will complete reliably — whether the async operation takes 1 second or 4 seconds — as long as it finishes within the 5-second timeout.

Recommendations