How to use JUnit to test asynchronous processes

Sam picture Sam · Mar 10, 2009 · Viewed 167.2k times · Source

How do you test methods that fire asynchronous processes with JUnit?

I don't know how to make my test wait for the process to end (it is not exactly a unit test, it is more like an integration test as it involves several classes and not just one).

Answer

Martin picture Martin · Dec 2, 2009

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