Mockito is an open source framework to create Mock in the automated drive test in Java environment. The latter is the framework recommended on developer.android.com and for which Google makes available the sample code. It can be used together with JUnit4 which is often already present in the Android Studio IDE.
Configuration with Android Studio
To use Mockito in Android Studio we just have to declare the dependency of “mockito-core” with Gradle. The following code line must be added to the build.gradle file:
We note that version 2.4.0 will be used, which is not the latest version but allows us to use Mockito together with PowerMock, another framework that will be analyzed later.
Using Mockito together with JUnit4
When you instantiate the test class, an annotation ”@RunWith(MockitoJUnitRunner.class)” must be added at the beginning of the test class. This annotation validates the correct use of the framework and simplifies the initialization of mock objects.
To create a Mock object in order to solve a certain dependency use “@Mock”.
Another powerful annotation is “@Spy” which allows you to create what we might call a partial mock, since if you don’t create a fake for a method then you will be called the real method. It is supposed to let the real method be used when we trust its behavior or when it is a reliable library code. If the fake for the spiate class is created, then it will be called the spiate class and not the real one.
Mockito APIs are countless, in this section we describe the ones used in tests performed on the Android App created by the author of this post. We note that these APIs can also be used with PowerMock.
Let’s start with when and thenReturn, which can be used to quickly create a fake method.
Let’s analyze keywords:
- when: wants as parameter the method of the mock object for which we want to create the fake, called with the “dot notation” as above;
- thenReturn: has as a parameter valoreDiRitorno, the object or value of the return variable (e.g. valoreDiRitorno can be an integer, or the object of a class).
Let’s analyze now doNothing which is used for void methods to make sure that the invocation of that method has no effect:
With this code when oggettoMock.metodoOggetto(param) is called, no operation will be performed. We note that we have specified a precise parameter and therefore the API will only work when the method has that parameter input.
In questo caso e nel precedente al posto di un parametro specifico possiamo usare anyInt(), anyString(). Ad esempio con anyInt() per qualsiasi intero passato per parametro fai una certa cosa. Nel caso di classi custom si può usare any(ClasseCustom.class), quindi per qualsiasi oggetto della classe ClasseCustom.
In this case and in the previous one we can use anyInt(), anyString() instead of a specific parameter. For example with anyInt() for any integer pass by parameter do a certain thing. In the case of custom classes, you can use any(ClassCustom.class) and then for any object in the ClassCustom class.
In some situations, during unit testing, we may be interested in knowing the value of the parameters with which a method has been called, be it with return The following code is used to capture these values:
Let’s analyze the code::
- ArgumentCaptor: is a Mockito class that allows you to capture values passed by parameter to a method. This is done using argumentCaptor.capture() instead of the method signature parameters (see line 3);
- with assertEquals check whether the parameter entered during execution corresponds to the desired one, you use argumentCaptor.getValue() to return the captured value.
With verify we can count the number of times a method is called up in our unit test. The comments include what each method does.
With the code of line 6 we can check whether getSomeThing(…) is called n times. In case this doesn’t happen Mockito launches self-explanatory exceptions that we could capture with a try catch and then assert a failure with JUnit, as in the following code. All these exceptions are MockitoAssertionError.
The Mockito framework not only creates mock objects and fake methods of a class, but can also “throw” an exception when a certain instruction is executed, e.g. a method is invoked. The syntax is as follows:
This code imposes that when the child() method of the mDatabaseReference object is invoked, whatever the string passed by parameter “anyString ()” will be thrown the exception NullPointerException(); in practice we can inject an exception during the execution of our code. This can be useful to check if our code handles exceptions correctly.
Advantages and disadvantages
In summary, the advantages of Mockito are:
- provides a huge amount of APIs to test classes and public methods;
- the java documentation is well done and exhaustive, you can also find many references in the literature;
- is a widely used framework in Android, in fact its use is recommended on developer.android.com.
- The real limit of this framework is the lack of access to private methods or private attributes of a class;
- It is not possible to create a fake of a static method;
- It can lead to code change for testing purposes, e. g. forces you to create getters and setters to access private attributes of the class to be tested.
To solve these problems you can use another framework called PowerMock (my “Medium” article), which is also based on Mockito, but extends its functionality.