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
Também na biblioteca
Trabalhando com Excel em PHP: bibliotecas PhpSpreadsheet e OpenSpout
Rate Limiting em PHP: guia completo para limitação de requisições
Agendador de tarefas PHP: cron-express
Envio de email em Java: biblioteca Jakarta Mail (JavaMail)
Aprendizado de Máquina em C# (.NET): visão geral das bibliotecas ML.NET, Accord.NET, TensorFlow.NET