Awaitility Java: guia completo com exemplos práticos

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Awaitility para Java: guia completo com exemplos práticos

1. O que é e para que serve

Awaitility é uma biblioteca poderosa para Java que oferece uma DSL (Domain-Specific Language) expressiva para escrever testes assíncronos. No desenvolvimento moderno, lidamos constantemente com operações assíncronas: requisições HTTP, acesso a bancos de dados, filas de mensagens, CompletableFuture, streams reativos e muito mais. Abordagens tradicionais de teste, como Thread.sleep(), resultam em testes frágeis, lentos e pouco confiáveis. O Awaitility resolve esse problema permitindo descrever expectativas de forma declarativa: "espere, mas não mais que 10 segundos, até que a condição se torne verdadeira, verificando a cada 100 milissegundos".

O principal valor da biblioteca é tornar os testes assíncronos estáveis, legíveis e eficientes. Em vez de adivinhar quanto tempo uma operação vai levar, você descreve o estado final esperado do sistema. O Awaitility gerencia automaticamente o tempo de espera, a frequência das verificações e o tratamento de exceções. Isso é especialmente importante ao testar microsserviços, cenários de integração e sistemas com arquitetura distribuída, onde o tempo de execução das operações pode variar bastante.

A biblioteca se integra com todos os frameworks de teste populares (JUnit 4/5, TestNG, Spock) e pode ser usada tanto em testes unitários quanto em testes de integração. O Awaitility não impõe abordagens específicas para assincronia — ele funciona com qualquer mecanismo: callbacks, Future, streams reativos, Event Bus, etc. O único requisito é a capacidade de verificar o estado do sistema em um determinado momento.

2. Instalação

O Awaitility é distribuído via Maven Central. Para adicioná-lo ao seu projeto, use o gerenciador de dependências da sua escolha.

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")

Verificando a versão

A versão mais recente pode ser consultada no MVNRepository. No momento da escrita deste artigo, a versão estável atual é a 4.2.1 (compatível com Java 8+).

3. Início rápido — exemplo mínimo funcional

Vamos ver um exemplo simples: temos um serviço que atualiza um valor de forma assíncrona. Queremos esperar até que o valor se torne igual a 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() {
        // Simula um serviço assíncrono
        AtomicInteger counter = new AtomicInteger(0);

        // Inicia uma thread em segundo plano que incrementa o contador
        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(200); // Simula processamento
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                counter.incrementAndGet();
            }
        }).start();

        // Awaitility espera até que o contador seja igual a 5
        Awaitility.await()
                .atMost(5, TimeUnit.SECONDS)
                .until(() -> counter.get() == 5);

        // Verifica o resultado
        assert counter.get() == 5 : "O contador deve ser igual a 5";
    }
}

Este teste é garantido de ser concluído

Recommendations