# Unit testing asynchronous methods with Mockito.

Testing asynchronous code is one of the biggest challenges we have as engineers. There are tools out there, which facilitate our job, so in this opportunity, let’s explore how a Framework like Mockito can help us to achieve this goal.

“Quality is never an accident; it is always the result of intelligent effort.”

## Introduction

After promising that I would be writing and maintaining my blog, here I go again (3289423987 attempt). So in this occasion I want to write about Mockito… yes, this mocking framework that is a “must have” when writing unit tests in Java ;).

This is article assumes that you know what a Unit Test is and why you should write tests in general.

Also I strongly recommend this famous article from Martin Fowler which talks about Test Doubles, yes, it is a must read to understand this concept that we are going to use accross this article.

## Common case scenario

Sometimes we have to test methods that use callbacks, meaning that they are asynchronous by definition.

These methods are not easy to test and using Thread.sleep(milliseconds) method to wait for the response is not a good practice and can convert your tests in non-deterministic ones (I have seen this many times in many code bases).

So how do we do this? Mockito to the rescue!

## Let’s see an example

Suppose we have a class called DummyCaller that implements a DummyCallback and has a method doSomethingAsynchronously() that delegates its functionality to a collaborator of the the class called DummyCollaborator that has a doSomethingAsynchronously(DummyCallback callback) as well, but receives a callback as a parameter (in this case our DummyCallback), so this methods creates a new thread to run his job and then gives us a result when is done.

Here is the code to understand this scenario in a better way:

public interface DummyCallback {
public void onSuccess(List<String> result);
public void onFail(int code);
}

public class DummyCaller implements DummyCallback {
private final DummyCollaborator dummyCollaborator;

private List<String> result = new ArrayList<String>();

public DummyCaller(DummyCollaborator dummyCollaborator) {
this.dummyCollaborator = dummyCollaborator;
}

public void doSomethingAsynchronously() {
dummyCollaborator.doSomethingAsynchronously(this);
}

public List<String> getResult() {
return this.result;
}

@Override
public void onSuccess(List<String> result) {
this.result = result;
System.out.println("On success");
}

@Override
public void onFail(int code) {
System.out.println("On Fail");
}
}

public class DummyCollaborator {
public static int ERROR_CODE = 1;

public DummyCollaborator() {
// empty
}

public void doSomethingAsynchronously (final DummyCallback callback) {
@Override
public void run() {
try {
callback.onSuccess(Collections.EMPTY_LIST);
} catch (InterruptedException e) {
callback.onFail(ERROR_CODE);
e.printStackTrace();
}
}
}).start();
}
}


## Creating our test class

We have 2 options to test our asynchronous method but first we will create our test class DummyCollaboratorCallerTest (for convention we just add Test at the end of the class so this becomes part of its name).

public class DummyCollaboratorCallerTest {
// Class under test
private DummyCaller dummyCaller;

@Mock
private DummyCollaborator mockDummyCollaborator;

@Captor
private ArgumentCaptor<DummyCallback> dummyCallbackArgumentCaptor;

@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
dummyCaller = new DummyCaller(mockDummyCollaborator);
}
}


So here we are using MockitoAnotations to initialize both Mock and ArgumentCaptor, but do not worry about them yet, cause this is what we will be seeing next.

The only thing to take into account here is that both mock and class under test are being initialized before each test is executed in the setUp() method (using the @Before annotation).

REMEMBER: For unit testing all the collaborators for a CUT (class under test) must be test doubles.

Let’s take a look at our 2 test solutions going forward.

## Setting up an answer for our callback

This is our test case using a doAnswer() for stubbing a method with a generic Answer.

This means that since we need a callback to return immediately (synchronously), we generate an answer so when the method under test is called, the callback will be executed right away with the data we tell it to return.

Finally we call our real method and verify state and interaction.

@Test
final List<String> results = Arrays.asList("One", "Two", "Three");
// Let's do a synchronous answer for the callback
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
((DummyCallback)invocation.getArguments()[0]).onSuccess(results);
return null;
}
}).when(mockDummyCollaborator).doSomethingAsynchronously(
any(DummyCallback.class));

// Let's call the method under test
dummyCaller.doSomethingAsynchronously();

// Verify state and interaction
verify(mockDummyCollaborator, times(1)).doSomethingAsynchronously(
any(DummyCallback.class));
assertThat(dummyCaller.getResult(), is(equalTo(results)));
}


## Using an ArgumentCaptor

Our second option is to use an ArgumentCaptor.

Here we treat our callback asynchronously: we capture the DummyCallback object passed to our DummyCollaborator using an ArgumentCaptor.

Finally we can make all our assertions at the test method level and call onSuccess() when we want to verify state and interaction.

@Test
public void testDoSomethingAsynchronouslyUsingArgumentCaptor() {
// Let's call the method under test
dummyCaller.doSomethingAsynchronously();

final List<String> results = Arrays.asList("One", "Two", "Three");

// Let's call the callback. ArgumentCaptor.capture() works like a matcher.
verify(mockDummyCollaborator, times(1)).doSomethingAsynchronously(
dummyCallbackArgumentCaptor.capture());

// Some assertion about the state before the callback is called
assertThat(dummyCaller.getResult().isEmpty(), is(true));

// Once you're satisfied, trigger the reply on callbackCaptor.getValue().
dummyCallbackArgumentCaptor.getValue().onSuccess(results);

// Some assertion about the state after the callback is called
assertThat(dummyCaller.getResult(), is(equalTo(results)));
}


## Conclusion

The main difference between both solutions is that when using DoAnswer() we are creating an anonymous inner class, and casting (in an unsafe way) the elements from invocation.getArguments()[n] to the data type we want, but in case we modify our parameters the test will “fail fast” letting know that something has happened.

On the other side, when using ArgumentCaptor we probably have more control cause we can call the callbacks in the order we want in case we need it.

In unit testing, this is a common case that sometimes we do not know how deal with, so in my experience using both solutions has helped me to have a robust approach when having to test asynchronous methods.

I hope you find this article useful, and as always, remember that any feedback is very welcome. Of course if you have any doubt do not hesitate to contact me.

## Code Sample

Here is the link where you can find this example and others. Most of them are related to Java and Android because this comes from a presentation I gave a couple of months ago: