diff --git a/libraries/pom.xml b/libraries/pom.xml
index ee5fb2f977..ff9c72399d 100644
--- a/libraries/pom.xml
+++ b/libraries/pom.xml
@@ -366,6 +366,18 @@
groovy-all
2.4.10
+
+ org.awaitility
+ awaitility
+ ${awaitility.version}
+ test
+
+
+ org.awaitility
+ awaitility-proxy
+ ${awaitility.version}
+ test
+
0.7.0
@@ -397,6 +409,7 @@
4.12
0.10
3.5.0
+ 3.0.0
diff --git a/libraries/src/main/java/com/baeldung/awaitility/AsyncService.java b/libraries/src/main/java/com/baeldung/awaitility/AsyncService.java
new file mode 100644
index 0000000000..3bc82afaac
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/awaitility/AsyncService.java
@@ -0,0 +1,50 @@
+package com.baeldung.awaitility;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class AsyncService {
+ private final int DELAY = 1000;
+ private final int INIT_DELAY = 2000;
+
+ private AtomicLong value = new AtomicLong(0);
+ private Executor executor = Executors.newFixedThreadPool(4);
+ private volatile boolean initialized = false;
+
+ public void initialize() {
+ executor.execute(() -> {
+ sleep(INIT_DELAY);
+ initialized = true;
+ });
+ }
+
+ public boolean isInitialized() {
+ return initialized;
+ }
+
+ public void addValue(long val) {
+ if (!isInitialized()) {
+ throw new IllegalStateException("Service is not initialized");
+ }
+ executor.execute(() -> {
+ sleep(DELAY);
+ value.addAndGet(val);
+ });
+ }
+
+ public long getValue() {
+ if (!isInitialized()) {
+ throw new IllegalStateException("Service is not initialized");
+ }
+ return value.longValue();
+ }
+
+ private void sleep(int delay) {
+ try {
+ Thread.sleep(delay);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/awaitility/AsyncServiceUnitTest.java b/libraries/src/test/java/com/baeldung/awaitility/AsyncServiceUnitTest.java
new file mode 100644
index 0000000000..4f07d556b9
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/awaitility/AsyncServiceUnitTest.java
@@ -0,0 +1,84 @@
+package com.baeldung.awaitility;
+
+import static org.awaitility.Awaitility.await;
+import static org.awaitility.Awaitility.fieldIn;
+import static org.awaitility.Awaitility.given;
+import static org.awaitility.proxy.AwaitilityClassProxy.to;
+import static org.hamcrest.Matchers.equalTo;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+import org.awaitility.Awaitility;
+import org.awaitility.Duration;
+import org.junit.Before;
+import org.junit.Test;
+
+public class AsyncServiceUnitTest {
+ private AsyncService asyncService;
+
+ @Before
+ public void setUp() {
+ asyncService = new AsyncService();
+ }
+
+ @Test
+ public void givenAsyncService_whenInitialize_thenInitOccurs1() {
+ asyncService.initialize();
+ Callable isInitialized = () -> asyncService.isInitialized();
+ await().until(isInitialized);
+ }
+
+ @Test
+ public void givenAsyncService_whenInitialize_thenInitOccurs2() {
+ asyncService.initialize();
+ Callable isInitialized = () -> asyncService.isInitialized();
+ await().atLeast(Duration.ONE_HUNDRED_MILLISECONDS)
+ .atMost(Duration.FIVE_SECONDS)
+ .with().pollInterval(Duration.ONE_HUNDRED_MILLISECONDS)
+ .until(isInitialized);
+ }
+
+ @Test
+ public void givenAsyncService_whenInitialize_thenInitOccurs_withDefualts() {
+ Awaitility.setDefaultPollInterval(10, TimeUnit.MILLISECONDS);
+ Awaitility.setDefaultPollDelay(Duration.ZERO);
+ Awaitility.setDefaultTimeout(Duration.ONE_MINUTE);
+
+ asyncService.initialize();
+ await().until(() -> asyncService.isInitialized());
+ }
+
+ @Test
+ public void givenAsyncService_whenInitialize_thenInitOccurs_withProxy() {
+ asyncService.initialize();
+ await().untilCall(to(asyncService).isInitialized(), equalTo(true));
+ }
+
+ @Test
+ public void givenAsyncService_whenInitialize_thenInitOccurs3() {
+ asyncService.initialize();
+ await().until(fieldIn(asyncService)
+ .ofType(boolean.class)
+ .andWithName("initialized"), equalTo(true));
+ }
+
+ @Test
+ public void givenValue_whenAddValue_thenValueAdded() {
+ asyncService.initialize();
+ await().until(() -> asyncService.isInitialized());
+ long value = 5;
+ asyncService.addValue(value);
+ await().until(asyncService::getValue, equalTo(value));
+ }
+
+ @Test
+ public void givenAsyncService_whenGetValue_thenExceptionIgnored() {
+ asyncService.initialize();
+ given().ignoreException(IllegalStateException.class)
+ .await()
+ .atMost(Duration.FIVE_SECONDS)
+ .atLeast(Duration.FIVE_HUNDRED_MILLISECONDS)
+ .until(asyncService::getValue, equalTo(0L));
+ }
+}