Why Mockito?

A Testing Tool

Kayathiri Mahendrakumaran
Geek Culture
4 min readNov 11, 2022

--

Photo by Tolga Ulkan on Unsplash

Mock.. PowerMock..

We may have came across these terms while writing tests for our code base. In unit testing, we wish to test a class’s functions separately. But generally, the classes are not independent. One class will invoke methods of another class. So, it is hard to test a single class.

  • Some of the external service we use may not properly work in the testing environment. Some of the functions may require database or cloud connections.
  • If external services are influenced in the testing, it is against the scope of the unit testing.

Here, we need a mechanism to cater these issues. This is when Mockito and PowerMock come to stage. They are open source tools for testing. They both hide the external service by replacing them with the mock objects.

So when to Mockito or PowerMock where both helps to create mock objects?

Testing code that follow good coding practices is very easy. But it is had to test the bad code base. Powermock allows testing bad code without doing a code level changes. Powermock allows to mock private methods where the testing on those logic are missed. This can reduce the chance of detecting bugs.

Therefore, it is a good option to use Mockito to test our code.

In this article, let’s see how to use Mockito in our testing.

Maven dependencies

In order to use the Mockito, you need to add the following dependency to the pom.xml file.

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.8.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>3.8.0</version>
<scope>test</scope>
</dependency>

Note: mockito-junit-jupiter is required for JUnit 5, if you are using JUnit 4 or TestNG then you can only add the mockito-core.

Mockito Mock Creation

The Mockito framework allows us to create mock objects using either @Mock annotation or mock() static method.

Mockito mock() Method

Service service = Mockito.mock(Service.class);
when(service.method(num1, num2)).thenReturn(expected);

Mockito.mock() method is used to create a mock object of Service class.

Mockito Mock Annotation

import static org.mockito.Mockito.when;

import org.junit.jupiter.api.BeforeEach;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

public class Test {

@Mock
Service service;

@BeforeEach
public void setup() {
MockitoAnnotations.initMocks(this);
}

@Test
public void test() {
when(service.method(num1, num2)).thenReturn(expected);
// other implementations
}
}

If we initialize the the mock object with @Mock or @Spy, we need to call MockitoAnnotations.initMocks(this); to initialize the mock objects.

We use when() and thenReturn() to specify the behavior of those mocked objects. To simply say, that in the above example, when service class method is invoked, it will return the expected value we provide.

If we mock an object, can we call the real method of that object? This is possible with the @Spy annotation.

Mockito Spy

Unless a preset behavior was defined, the real method will be called when you call a spied object’s method. As mentioned in the above example, we can use when() and thenReturn() methods to change the method behavior.

How this is possible with the void methods? Let’s analyze further on mocking void methods.

Mock void methods

Void methods can be mocked with Mockito’s doNothing(), doThrow(), and doAnswer() methods.

Service service = mock(Service.class);
doNothing().when(service).method2(x,y);

However, doNothing() is Mockito’s default behavior for void methods.

DoThrow() generates an exception:

Service service = mock(Service.class);
doThrow().when(service).method2(x, isNull());

Why do we try to mock a void method? One reason is to capture arguments.

We might need to record the arguments, though, in order to use them further. In these cases, we can use an ArgumentCaptor:

Service service = mock(Service.class);
ArgumentCaptor<String> valueCapture =
ArgumentCaptor.forClass(String.class);
doNothing().when(service).method2(x, valueCapture.capture());
service.method2(x, "y");
assertEquals("y", valueCapture.getValue());

A method is not limited to adding or setting values; it can also carry out more sophisticated actions. In this situations, Mockito’s doAnswer() can help. Let’s try this with the following example.

Service service = mock(Service.class);
doAnswer(invocation -> {
Object arg0 = invocation.getArgument(0);
Object arg1 = invocation.getArgument(1);

assertEquals(4, arg0);
assertEquals(y, arg1);
return null;
}).when(service).method2(any(Integer.class), any(String.class));
service.method2(4, y);

Now we can mock these objects with the above options. But what if we need a real implementation of that mock object. The answer is @Spy. Another option is to partial mocking.

Partial Mocking

doCallRealMethod() can be used here.

Service service = mock(Service.class);
doCallRealMethod().when(service).add(any(Integer.class), any(String.class));

Here, we can use Mockito’s verify() method to ensure that this particular method is invoked.

Service service = mock(Service.class);
doCallRealMethod().when(service).add(any(Integer.class), any(String.class));
service.add(x,"y");
verify(service).add(x, "y");

Mock static methods

It was a difficult task to mock static method with mockito. We had to use additional libraries or powerMock. But, after the Mockito version 3.4.0 the things changed significantly.

Now, we can do this only with Mockito! We will see how to consume this feature.

Assume you are using an external library or your own static method in the class that you need to test.

Here, you only need mockito-core and mockito-inline .

public class ExtService{
public static String method3(){
return "dummy";
}
}

Test class with mock static.

try(MockedStatic<ExtService> theMock = Mockito.mockStatic(ExtService.class)){
theMock.when(ExtService::method3).thenReturn("mocked string");
assertEquals(theMock.method3(), "mocked string");
}

Hope you get an idea on using Mockito to test your code base.

Photo by Tim Mossholder on Unsplash

Thanks for reading!!!

Reference

  1. https://blog.codecentric.de/junit-testing-using-mockito-powermock
  2. https://www.baeldung.com/mockito-void-methods

--

--

Kayathiri Mahendrakumaran
Geek Culture

Senior Software Engineer 👨‍💻, WSO2 | Undergraduate👩‍🎓 , Computer Science & Engineering | Writer ✍️