Unit testing asynchronous methods with Mockito

After promising (and not keeping my promise) that I would be writing and maintaining my blog, here I go again (3289423987 attempt). But lest’s forget about that…
So in this occasion I wanted to write about Mockito…yes, this mocking framework that is a ‘must have’ when writing your unit tests ;).


This is article assumes that you know what a unit test is and why you should write tests.
Also I strongly recommend this famous article from Martin Fowler that talks about test doubles, it is a must read to understand about test doubles.

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 to be honest).
So how do we do this? Mockito to the rescue!

Let’s put 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:

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).

So here we are using MockitoAnotations to initialize both Mock and ArgumentCaptor, but don’t 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 that 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.

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.

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.


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.
As interest 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, as well as other ways of doing this. 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 with Java and Android because this comes from a talk I gave a couple of months ago.
The presentation is in english but the video is in spanish (sorry for those who do not understand my argentinian accent…haha…BTW I will try to upload an english version as soon as possible…)

Further Reading

I highly recommend to take a look at Mockito documentation to have a better understanding of the framework. The documentation is very clear and has great examples. See you!

Leave a Reply