views:

1297

answers:

4

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)

+5  A: 

Start the process off and wait for the result using a Future.

Tom Hawtin - tackline
+8  A: 

IMHO it's bad practice to have unit tests create or wait on threads, etc. You'd like these tests to run in split seconds. That's why I'd like to propose a 2-step approach to testing async processes.

  1. Test that your async process is submitted properly. You can mock the object that accepts your async requests and make sure that the submitted job has correct properties, etc.
  2. Test that your async callbacks are doing the right things. Here you can mock out the originally submitted job and assume it's initialized properly and verify that your callbacks are correct.
Cem Catikkas
+1  A: 

An alternative is to use the CountDownLatch class.

public class DatabaseTest
{

/** Data limit */
private static 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;
            synchronized (lock)
            {
                lock.countDown();
            }
        }
    });

    synchronized (lock)
    {
        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.

Strawberry
+1  A: 

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

Johan