Add awaitility module: testing async @Async/@Scheduled/@KafkaListener code without Thread.sleep

Covers replacing Thread.sleep with await() across a void @Async method, an
@EmbeddedKafka-backed @KafkaListener, and an already-running @Scheduled job;
verifies Awaitility 4.3.0's real defaults (10s timeout, 100ms poll interval)
and its default-uncaught-exception-handler swap directly against the jar;
and documents a real pom.xml trap where Boot 4.1.1 split Kafka's
autoconfiguration (spring-boot-kafka) out of spring-kafka itself, which
silently leaves @KafkaListener beans with no running container.
This commit is contained in:
Claude
2026-10-08 15:18:58 +00:00
parent 09631dcaab
commit a7b76243fa
31 changed files with 900 additions and 0 deletions
@@ -0,0 +1,31 @@
package com.ankurm.awaitility;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.springframework.stereotype.Component;
/**
* Stands in for "the side effect of an asynchronous operation" — a row written by a
* background thread that a test (or another part of the application) has no handle to wait on
* directly. {@link AsyncGreetingService#sendConfirmation(String)} writes here; nothing returns a
* {@code Future} for it to block on, which is the whole reason the test for it needs Awaitility
* rather than a blocking {@code get()}.
*/
@Component
public class Mailbox {
private final ConcurrentMap<String, String> sent = new ConcurrentHashMap<>();
void record(String orderId, String message) {
sent.put(orderId, message);
}
/** Returns {@code null} if nothing has been recorded for this order yet. */
public String confirmationFor(String orderId) {
return sent.get(orderId);
}
public int size() {
return sent.size();
}
}