Mockito

Language: Java

Testing

Mockito was created to simplify unit testing in Java by providing an easy-to-use API for mocking dependencies. It allows developers to focus on testing the class under test without needing real implementations of its collaborators.

Mockito is a popular Java testing framework used to create mock objects for unit testing. It allows developers to simulate the behavior of real objects and verify interactions, enabling isolated and controlled tests.

Installation

maven: Add org.mockito:mockito-core dependency in pom.xml
gradle: Add testImplementation 'org.mockito:mockito-core:5.6.0' in build.gradle

Usage

Mockito allows creating mock objects, stubbing methods, verifying interactions, and capturing arguments. It integrates well with JUnit and supports annotations such as `@Mock`, `@InjectMocks`, and `@Spy` for cleaner test code.

Creating a mock object

import static org.mockito.Mockito.*;

List<String> mockedList = mock(List.class);
mockedList.add("one");
verify(mockedList).add("one");

Creates a mock List, calls a method, and verifies that the method was invoked with the correct argument.

Stubbing method behavior

when(mockedList.get(0)).thenReturn("first");
System.out.println(mockedList.get(0)); // prints 'first'

Defines a return value for a method when called on a mock object.

Injecting mocks into a class

import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

public class UserServiceTest {

    @Mock
    private UserRepository userRepository;

    @InjectMocks
    private UserService userService;

    @BeforeEach
    void init() {
        MockitoAnnotations.openMocks(this);
    }
}

Injects mock dependencies into the class under test automatically using `@InjectMocks`.

Using @Spy for partial mocks

@Spy
List<String> spyList = new ArrayList<>();
spyList.add("one");
verify(spyList).add("one");

Allows calling real methods while still being able to verify interactions or stub certain methods.

Argument captor

import org.mockito.ArgumentCaptor;
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(mockedList).add(captor.capture());
System.out.println(captor.getValue());

Captures arguments passed to mock methods for detailed verification.

Verifying number of invocations

verify(mockedList, times(2)).add("one");

Verifies that a method was called a specific number of times.

Error Handling

UnnecessaryStubbingException: Occurs when a stubbed method is never called. Remove unused stubs or set Mockito to lenient mode.
MockitoException: Ensure that mock objects are initialized properly using `MockitoAnnotations.openMocks()` or the `@ExtendWith(MockitoExtension.class)` JUnit 5 integration.
NullPointerException on mock: Verify that the mock object is created using `mock()` or `@Mock` and not null before use.

Best Practices

Use mocks only for external dependencies, not the class under test.

Prefer `@Mock` and `@InjectMocks` annotations for cleaner tests.

Use `verify` to ensure critical interactions with dependencies.

Keep tests focused and independent; avoid relying on actual implementations of collaborators.

Leverage argument captors to validate the actual data passed to mocks.