As you probably already know, we do care about tests. We write complex applications and at the same time we like to keep our code as simple and readable as possible. For this reason we often look at the code with a critical eye, trying to find a nice way to clean it up. And when you refactor your code that frequently, you can find your best friends in the bunch of tests that make you sure you are not breaking the current behaviour of your software. Moreover, given that a single Java class should have a single and clear responsibility it’s likely that it has few (I mean very few) collaborators to which it can delegate part of the job. So, how do we test these cases of cooperation? We use Mockito.
is mockito a good drink?
“Mockito is a mocking framework that tastes really good. It lets you write beautiful tests with clean & simple API. Mockito doesn’t give you hangover because the tests are very readable and they produce clean verification errors.” That’s the description you can find on its web page. In a nutshell Mockito enables you to mock collaborators for the class under test, eventually stub their methods so that they behave in the way you want, and finally verify that the actual cooperation between them is how you really expected. All this in a very simple way.
I’ll use a simple example in order to show you some of the most frequently used parts of the Mockito API. Let’s suppose you want to test a
UserController class, that has two collaborators: a
UserProvider that is in charge to invoke a remote service in order to retrieve data for a particular user and a
UserStore that takes care of storing these data. Basically the
UserController class looks like this:
As we can see, the
UserProvider collaborator can effectively return requested data or throw a
ResourceNotFoundException in case the user doesn’t exist. In that circumstance the
UserStore shouldn’t be called at all, since there’s nothing to store. Let’s test this cooperation between our actors using Mockito.
mock your collaborators
First of all, we are obviously not going to use a real user provider nor a real user store for testing purposes. We really don’t need them at this point, this is not an integration test and we want our test to be fast. So let’s mock our collaborators and teach them how they should behave. Mocking objects is incredibly simple with Mockito, all you need to do is to add a
@Mock annotation when you define them. Then you can inject them in your object under test. For example:
verify cooperation in successful case
Let’s test the successful case first, where our
userProvider collaborator effectively returns the user we look for.
At line 4 we’re using Mockito APIs for instructing our
userProvider collaborator to return a specific
User instance when its
getById method is called with a particular user id. It reads really well, like a sentence: dear provider, when your
getById method is called, then (please) return this user instance. In this example we are passing a real
int in the
getById method, but if we weren’t interested in the actual input, we could have used
Mockito.anyInt method instead that returns an instance of argument matcher that accept any
int as an argument.
At line 6 we call the method we want to test and then it’s time to verify that our collaborators have been correctly invoked. At line 8, for instance, we check that
getByIdmethod have been called on
userProvider exactly once. For that purpose we use
Mockito.verify method, passing the mocked collaborator and the desired verification mode. Mockito provides really well named methods we can use for expressing verification modes: here for example we’re using
Mockito.times specifying the exact number of times we want the method called. Other examples of methods are
Mockito.atMost, just pick up the one fits better for you!
Given that we taught the provider to return a specific instance of user when its
getById method is called, we can now verify that we are actually storing that user. Therefore at line 9 we verify that
userController is calling the
storemethod of the mocked
userStore, exactly once, passing our user instance as argument.
verify cooperation in exceptional case
Ok, we tested successful case, but we know that in reality a userProvider can throw a
ResourceNotFoundException if it can’t find a user. What we want to test in that case is that
userStore collaborator is not called at all, since we have nothing to persist. Here is the test code:
What you can spot here is that we are instructing our mocked
userProvider in a slightly different way. Now we are asserting: lovely provider, when your
getById method is called with that particular user id, then (please) throw a
ResourceNotFoundException. Once we have given the provider the time to learn its new job, we can call the method under test again and verify if everything worked as expected. In particular now we just want to check that
userController has not been invoked, with any user instance, using
Mockito.never as a verification mode and
Mockito.any as an argument matcher (since we are not really interested in the argument).
and how do you mock?
With this example we covered Mockito’s aspects we use the most in our everyday coding life, but there are many other interesting features it’s worth to have a look at, so I suggest you visit its web page for more information. What are your opinions about it? Do you use any other mocking framework? Or maybe you don’t use them at all? We are interested in what your favourite approach to mocking is, so we invite you to leave a comment below or Tweet us!