Mockito

17 Jun 2017 View Comments #mockito #testing #framework #mock

Mockito is a popular open-sourced Java mocking framework which is used for testing. The idea of mocking is widespread out in many other languages because it is indeed useful and essential for creating unit tests.

Mockito? what is it?

You may be unfamiliar with the term, mock. A mock is like creating a disguised thing that behaves like the real thing which can execute given instructions. The Mockito is a tool to do just that. A mock would not actually create any real object so it just creates a type of a thing you are mocking.

For example (using the famous list example):

Let’s take a look at the example of what I mean by creating a type. testIntsMock is a mock object of a List:

Note the mocked list (testIntsMock) did not actually add any values but we’ve successfully verified that the add operation is called which ensures us that functionally it is doing what it supposed to do.

Let’s say that we wanted actual behavior changes with the mocked item. The Mockito supports this as well. We can use Spy instead of plain Mock to do our mocking:

Note the Spy list is now has the actual size 3 instead of 0 from our Mock example. So why use Spy? Well, the example above revealed already a couple of powerful mocking ability the Spy can do instead of using a real object. You can manipulate the spied object using when/doAnswer etc. Also, you can make verify calls to ensure the function you are testing is working.

Examples

Examples are available and found easily online. It is redundant to duplicate their work here. I would encourage you to look for examples or examples are found in various tests in src/test of my Java algorithm playground

Best Practices using Mockito

1. Unit tests vs Functional Tests

Mockito is mainly written for unit tests which enable you to write tests for each function separately. It creates mocked types which essentially may be ignored for testing DAO (DB object) or streams (compression, file, iterators, a flow of data) or rendering or anything that might require complicated work, you can abstract those using mocks. In an ideal testing environment, we can have unit tests testing on every change as part of CI then those complicated work can be tested via functional tests (which also can be as part of CI) running every night. In my opinion, this is a good testing layout which will ensure end-to-end functionalities are also covered for testing as well as the unit tests which will be just a quick tests via Mocking.

This one is an obvious item. You are not going to write good unit tests using various mocking abilities without knowing exactly what is happening in the code you are trying to mock. For example, you should not simply mock string encode operation when the operation is expected to be done as part of the function. Also, when you are mocking an item. You need write tests as precise and readable as you can because tests with mocking can easily lose tracks and change behaviors upside down quite easily. It will not only help others but most importantly it will help you who will eventually write the tests out. Writing clean and neat tests are for you, not for others.
3. Be aware of mocking types you don't own

This is something programmers often look down. They do not find this important as they use trusted 3rd party libs that won't dramatically change their behaviors. This is a big mistake though. I have seen many libs which changed its behaviours drastically that the mocked tests would still pass as we have mocked the the entire 3rd party lib function. It is usually wrong and dangerous thinking to assume things will behave the way it is. For 3rd party libs, we have associated versions in dependency list to make sure behaviour stick to the way the software is expecting. So there will be a time when the version will need to go up. Now, let's say we reviewed over all of its changelogs carefully. Does this mean we will remember how its usage been written in every test? Wouldn't it be safer to not mock any of its behaviours so we have the red flags (errors) when running the tests?

Useful Mockito Usage

I find the following Mockito functionalities most useful at least from my experiences. It is definitely worth mentioning here.

Answer is a powerful mockito behavior which enables an idea of callbacks when things are called. This is very useful if you are wish to change the behaviours of a specific function of an another mocked object. 2 Examples on how I use Answers:

Or you can also have when at the end using doAnswer:

• Inorder

Inorder is a great way to verify order / sequence of method calls. Here is an example usage as examples are better than 1000 words:

This will make sure that firstMock’s methodOne is called before secondMock’s methodTwo is invoked.

• Capture

You can use mockito's capture ability to capture any values you need to assert later. Here is an example from Mockito's javadoc:

Above will capture the object, Person, which would let you use it to assertValues are what you expected at the end.

This is very useful as there are times where you would like the Mockito to capture the value as they are being verified which later you will be able to assert.