Mockito Basics: How to create mocks, stub methods, and verify expectations

Asad Mahmood
4 min readJun 4, 2023

--

In this article we will learn about how we can use Mockito framework to perform unit testing. Mockito allows you to create mock objects. Mock objects are objects that simulate the behavior of real objects, but they are not actually real objects. This allows you to isolate the code that you are testing from the code that it depends on. If you are new to unit testing, or just haven’t idea of unit testing check it out:

What is Mocking

The basic concept of mocking is replacing real objects with doubles. Let’s imagine we have a service that processes data from a database. It’s very cumbersome to set up a whole database just to test that service. To avoid setting up a database for the test, we create a mock that pretends to be the database.

Here Mockito comes into play. Mockito is a very popular library that allows us to create such mock objects.

How to Create Mocks with Mockito

Now let’s look at the different ways of creating mocks for our needs. Mockito creates test doubles of the type mock, but they have some features of a spy. These extra features allow us to verify if a certain method was called after we executed our test case.

Let’s continue with the first variant to create a mock with Mockito. This variant doesn’t require any framework or annotations. It is applicable in every project where we have included Mockito.

val subscriptionRepo = Mockito.mock(SubscriptionRepository::class.java)
val subscriptionService = SubscriptionService(subscriptionRepo)

We can simply declare a variable with the type of the component we want to mock. Taking the example from above, we want SubscriptionRepository to be a mock so that we don’t have to rely on its dependencies (like a database). The mock is then passed to the service, which is the system under test.

In case we have multiple dependencies that must be mocked, it gets cumbersome to create each and every mock manually with the variant shown above. So, we can also create mocks by using the @Mock annotation:

class SubscriptionServiceTest{

@Mock
lateinit var userRepo: UserRepository

@Mock
lateinit var subscriptionRepo: SubscriptionRepository


lateinit var subscriptionService: ISubscriptionService

@Before
fun setUp() {
openMocks(this)
subscriptionService = SubscriptionService(subscriptionRepo,userRepo)
}
}

We can annotate each field to be a mock with the annotation of @Mock. Annotating them doesn’t initialize them yet. To do so, we call MockitoAnnotations.openMocks(this) in the @Beforesection of our test. The annotated fields of the provided object are then initialized and ready to use, which is in our case is the class instance itself (this). We don’t have to deal with boilerplate code anymore and can keep our unit tests neat and clean.

Defining the Behavior of Mocks

In this section, we have a look at how to define the behavior of the mocks in our test. What we have seen until now is what mocks are used for and how to create them. We are ready to use them in our test cases.

The probably most common case when using Mockito is to return expected objects. If we call getSubscriptionStatus(userId) on SubscriptionService we would expect that the argument for userId is forwarded to the repository which returns a Status of a Subscription.

@Test
fun getSubscriptionStatus() {
val userId = "1112"
`when`(subscriptionRepo.getSubscriptionStatus(userId)).thenReturn(Subscribed)
val status = subscriptionService.getSubscriptionStatus(userId)
assertEquals(Subscribed, status)
}

We first declare userId. Having that expected userId, we can define the behavior of the mock which is to return the SubscriptionStatus of the expected user. We do so by calling Mockito.when() with the call we want to make. As a last step, we must declare the return value of that call at the end of the method chain.

If we try to get subscription status of a user, the service will return the previously declared object. We can assert that the expected Status equals the actual Status from the service.

How to Verify a Method Call

We can’t advise Mockito to return a value on void methods. In this case it is better to assert an underlying component was called. This can be achieved by using Mockito.verify():

@Test
fun removeSubscription(){
val userId = "1112"
subscriptionService.removeSubscription(userId)
verify(subscriptionRepo).removeSubscription(userId)
}

In this example, it isn’t necessary to declare the behavior of the mock beforehand. Instead, we just query the mock if it has been called during the test case. If not, the test case fails.

Conclusion

After this article, you should be able to create mocks for unit tests. Mock objects are a powerful tool for unit testing. Mockito gives us a lot of flexibility, and the freedom to choose between numerous tools to achieve our goals.

Thanks for reading this article. Be sure to click 👏 below to applause this article if you found it helpful. It means a lot to me. You can write me via comments, Twitter , or Linkedin.

--

--