How to use JUnit to test asynchronous processes How to use JUnit to test asynchronous processes java java

How to use JUnit to test asynchronous processes


An alternative is to use the CountDownLatch class.

public class DatabaseTest {    /**     * Data limit     */    private static final int DATA_LIMIT = 5;    /**     * Countdown latch     */    private CountDownLatch lock = new CountDownLatch(1);    /**     * Received data     */    private List<Data> receiveddata;    @Test    public void testDataRetrieval() throws Exception {        Database db = new MockDatabaseImpl();        db.getData(DATA_LIMIT, new DataCallback() {            @Override            public void onSuccess(List<Data> data) {                receiveddata = data;                lock.countDown();            }        });        lock.await(2000, TimeUnit.MILLISECONDS);        assertNotNull(receiveddata);        assertEquals(DATA_LIMIT, receiveddata.size());    }}

NOTE you can't just used syncronized with a regular object as a lock, as fast callbacks can release the lock before the lock's wait method is called. See this blog post by Joe Walnes.

EDIT Removed syncronized blocks around CountDownLatch thanks to comments from @jtahlborn and @Ring


You can try using the Awaitility library. It makes it easy to test the systems you're talking about.


If you use a CompletableFuture (introduced in Java 8) or a SettableFuture (from Google Guava), you can make your test finish as soon as it's done, rather than waiting a pre-set amount of time. Your test would look something like this:

CompletableFuture<String> future = new CompletableFuture<>();executorService.submit(new Runnable() {             @Override    public void run() {        future.complete("Hello World!");                    }});assertEquals("Hello World!", future.get());