Testing Applications with JUnit5 and Mockito. Part 1
There are a lot of good projects already written to help us facilitate the usage of mock objects in our Java projects. In this article series, we take a closer look at three of the most widely-used mock frameworks: EasyMock, JMock and Mockito. We end the series with Mockito.
1. Using Mockito
We know how to work with EasyMock and JMock. Let’s introduce the Mockito framework (https://site.mockito.org/), another popular mocking framework.
In order to work with Mockito, you need to add to the pom.xml file the dependency from listing 1:
Listing 2 presents a very simple Account object with two properties: an account ID and a balance.
Listing 3 shows the AccountManager interface that manages the life cycle and persistence of Account objects (limited to finding accounts by ID and updating accounts):
Listing 4 shows the shows the transfer method designed for transferring money between two accounts. It uses the previously defined AccountManager interface to find the debit and credit accounts by ID and to update them.
We want to be able to unit test the AccountService.transfer behavior. For that purpose, until the implementation of the AccountManager interface is ready, we will use a mock implementation of the AccountManager interface because the transfer method is using this interface, and we need to test it in isolation.
Trying to introduce Mockito, we create the TestAccountService test using Mockito, as in listing 5.
Into the listing we do the following:
- As usual, we start the listing by importing all the necessary objects we need (1). This example using the Mockito framework doesn’t rely on static import features.
- We extend this test using MockitoExtension (2). @ExtendWith is a repeatable annotation which is used to register extensions for the annotated test class or test method. For this Mockito example, we’ll only note that this extension is needed in order to create the mock objects through annotations, as we do at (3). This tells Mockito to create a mock object of type AccountManager.
- Like any of the previous listings, we declare two accounts which we’ll use to transfer money in between (4).
- In (5) we start declaring the expectations, by using the when method. Additionally, we use the lenient method in order to modify the strictness of objects mocking. Without this one, only one expectation declaration is allowed for the same findAccountForUser method, but we need two (one for the “1” argument and one for the “2” argument).
- In (6) we start the transfer from the one account to the other, and after that we assert the expected results (7).
The code snippet from listing 6 opens an HTTP connection to a given URL and reads the content at that URL. Suppose that this code is one method of a bigger application that you want to unit test.
In this listing:
- We open an HTTP connection (1).
- We read all the content that is received (2).
- If an error occurs, we return null (3).
What we want to test is the getContent method of the WebClient. For this purpose, we need to mock all the dependencies to that method. In this example we’ve two dependencies—one is the ConnectionFactory and one is the InputStream. Following the pattern with EasyMock and JMock, let’s try showing the WebClient test, this time using Mockito.