Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java unit testing - how to unit test an async method (uses callback) with mockito answer

I have the following method in the class Logic

public class Logic implements ILogic {

@Override
public void doSomethingInterestingAsync(final int number, 
                                        final ICallback callback){
    new Thread(new Runnable() {
        @Override
        public void run() {
            callback.response(number+1);
        }
    }).start();
  }
}

and I usually call it using

ILogic.doSomethingInterestingAsync(1, new ICallback() {
    @Override
    public void response(int number) {
        System.out.println(String.format("response - %s", number));
    }
});

Now I want to unit test it.

So I figured one solution is with CountDownLatch (found in other SO thread)
As Follows:

@Test
public void testDoSomethingInterestingAsync_CountDownLatch() throws Exception {
    final CountDownLatch lock = new CountDownLatch(1);

    ILogic ILogic = new Logic();
    final int testNumber = 1;
    ILogic.doSomethingInterestingAsync(testNumber, new ICallback() {
        @Override
        public void response(int number) {
            assertEquals(testNumber + 1, number);
            lock.countDown();
        }
    });
    assertEquals(true, lock.await(10000, TimeUnit.MILLISECONDS));
}

And it works great.
But I have also read that about Answer in Mockito might be a better practice for that,
But I couldn't quite follow the examples.
How do I write unit tests for methods using call backs using Mockito tools?
Thanks.

like image 483
Bick Avatar asked Aug 02 '14 21:08

Bick


1 Answers

I didn't understand why you need the CountDownLatch to begin with (judging by the code you posted), so I'm going to skip that in my answer, feel free to add a comment explaining what I'm missing.

I'd test it as follows:

@Test
public void testDoSomethingInterestingAsyncIncrementsParameter() {
    ILogic logic = new Logic();
    ICallback callback = mock(ICallback.class);

    logic.doSomethingInterestingAsync(SOME_NUMBER, callback);

    verify(callback, timeout(1000)).response(SOME_NUMBER + 1);
}
like image 157
ethanfar Avatar answered Nov 14 '22 16:11

ethanfar