Mockito is one of the most popular mocking frameworks used in Java applications for effective unit testing. The main feature of this framework is defining mocked and spied objects. In this article, we will cover @Mock annotation that is an alternative for the Mockito.mock() method.
2. Enable Mockito Annotations
Mockito annotations in unit tests could be enabled using one of the following ways:
by marking test class with @RunWith(MockitoJUnitRunner.class) annotation:
by calling the MockitoAnnotations.initMocks() method explicitly in set up method:
by using dedicated MockitoRule:
3. Creating mock objects
Let's start with a simple definition of a mock object - it is a dummy implementation for a real interface or a class in which you can define the return values for specific method calls. Mock objects usually are configured in tests to perform a particular behavior.
Mockito provides two methods to create mock objects:
using the static Mockito.mock() method,
using the @Mock annotation.
To use @Mock, first, we need to enable Mockito annotations - methods to do that were described in point 2.
Mockito can be used in conjunction with the JUnit framework, so our example tests will be based on that library:
@Mock MyDatabaseConnection myDatabaseConnection; - tells Mockito to mock the MyDatabaseConnection class,
MyService myService = new MyService(myDatabaseConnection); - instantiates the MyService class using the created mock object (notice that instead of this we could use @InjectMocks annotation),
when(myDatabaseConnection.update(anyString())).thenReturn(10); - configure the return value of mocked MyDatabaseConnection object,
Calling the test method:
boolean success = myService.updateRows("update table set col = 'val'"); - executing updateRows method from tested object,
verify(myDatabaseConnection, times(1)).openConnection(); - checking if openConnection() was called on mocked object once,
verify(myDatabaseConnection).update("update table set col = 'val'"); - checking if the update method was called on mocked object,
Assert.assertTrue(success) - checking if the called method from test object returned true.
As you can see we can create a mock instance of an object regardless of whether it is an interface or class. It possible to stub method calls to that mock using the Mockito.when(x).thenReturn(y) notation.
4. Configuring mock objects
Mocks can act differently depending on input parameters. To configure the behavior of the methods in mocked objects we could use when(...).then(...) syntax. Methods like anyString(), anyInt(), any(class) could be used to define that depends on the input parameter type a specific value should be returned. The when(...).thenThrow(...) syntax is used to throw an exception when special conditions are met.
Let's extend our test class with a few more tests:
We can use the verify() method on the mock object to check if the method has been called with the specific parameters and a certain number of times. That information is available because Mockito monitors all the methods calls and their parameters to the mock object.
In this article, we presented how to configure mock objects in Mockito tests and verify the behavior of the test class. With the Mockito framework, we can write tests for classes using external systems (like database, filesystem) easily.