Mockito is an open-source framework for creating mock objects in Java and Kotlin unit tests, which allows isolating the tested code from external dependencies. With its help, a developer replaces real repositories, API clients, and databases with controlled stubs that have predefined behavior. According to Mockito.org, the library is used in more than 60% of Java projects that use unit testing.
Key Takeaways
Mockito is an open-source library for creating mock objects (stubs) in unit tests for Java, Kotlin, and other JVM languages. Unlike JUnit, which handles test execution, Mockito solves the isolation problem — it replaces real dependencies of the tested class with predictable objects.
Without mocks, testing a method that accesses a database or external API requires setting up a real environment — deploying a database, starting a server. Mockito replaces these dependencies with objects that have fixed behavior: the repository.findById(1) method always returns a given User object without accessing the database.
Mockito’s architecture is based on the Proxy pattern (for interfaces and classes). The library generates a subclass or proxy for the specified type and intercepts all method calls, returning default values or values set via when().thenReturn().
The principle of Mockito’s operation is built on three basic operations: creating a mock, configuring behavior (stubbing), and verifying calls (verification). Each operation uses static methods from the org.mockito.Mockito class — the most downloaded class in the Java ecosystem according to Maven Central statistics. All mock method calls are recorded in memory, allowing later verification through verify.
A typical test with Mockito consists of three phases: Arrange — creating mocks and configuring stubs via when().thenReturn(), Act — calling the tested method, Assert — checking the result via assertEquals and verify(mock). This approach is called AAA (Arrange-Act-Assert).
Let’s look at a simple test where Mockito replaces a user repository. The when().thenReturn() method configures the mock so that the findById call returns a pre-prepared User object.
// Creating a repository mock
UserRepository mockRepo = mock(UserRepository.class);
// Configuring behavior: findById(1) returns a user
when(mockRepo.findById(1)).thenReturn(new User("Alice"));
// Checking that the method was actually called
User result = mockRepo.findById(1);
assertEquals("Alice", result.getName());
verify(mockRepo).findById(1);
Mockito provides two ways to create mocks: the static mock(Class) method and the @Mock annotation with initialization via MockitoAnnotations.openMocks(). The first approach is compact for one or two mocks, the second is convenient when there are many dependencies — annotations reduce boilerplate code.
The mock() method takes a class and returns a stub object that can be configured via when().thenReturn(). All unconfigured methods return default values: 0 for numbers, false for boolean, null for objects.
ApiClient apiClient = mock(ApiClient.class);
Database database = mock(Database.class);
The @Mock annotation combined with @ExtendWith(MockitoExtension.class) automatically creates mocks for all fields of the test class. The MockitoExtension is responsible for initialization before each test.
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void getUserShouldReturnUserFromRepo() {
when(userRepository.findById(1)).thenReturn(new User("Alice"));
User result = userService.getUser(1);
assertEquals("Alice", result.getName());
}
}
Stubbing is the process of defining what a mock method should return when called with specific arguments. The basic syntax: when(mock.method(args)).thenReturn(value). For different scenarios, Mockito offers several then-method variants.
| Method | Purpose |
|---|---|
| thenReturn(value) | Always returns the specified value |
| thenThrow(exception) | Throws an exception when called |
| thenAnswer(answer) | Calculates the return value dynamically |
| thenCallRealMethod() | Calls the real method (partial mock) |
When the return value depends on the call arguments, thenAnswer is used with a lambda. This is useful for simulating work with real data — for example, generating an ID based on the passed object.
when(repository.save(any())).thenAnswer(invocation -> {
User user = invocation.getArgument(0);
user.setId(42);
return user;
});
Verify is a unique feature of Mockito that older mock object libraries (EasyMock, jMock) do not provide.
Verify makes tests more reliable because it checks not only the return value but also side effects — calls to methods that don’t return a result (void methods). The verify(mock).methodName(args) method checks whether a specific mock method was called with the specified arguments. This allows testing not only the result but also the process — the fact of accessing the dependency.
By default, verify checks that the method was called exactly once. If a different count is needed, times(n), atLeast(n), never(), and other modifiers from the Mockito class are used.
// Checking the number of calls
verify(repository, times(3)).save(any());
verify(repository, never()).delete(any());
verify(repository, atLeastOnce()).findById(1);
// Checking the order of calls
InOrder inOrder = inOrder(repository);
inOrder.verify(repository).save(any());
inOrder.verify(repository).flush();
When you need to check exactly which object a method was called with, ArgumentCaptor is used. It captures the argument value during the call and allows checking its fields individually. ArgumentCaptor is especially useful when the tested code creates an object internally and passes it to a dependency — you cannot check that object otherwise.
ArgumentCaptor<User> captor = ArgumentCaptor.forClass(User.class);
verify(repository).save(captor.capture());
assertEquals("Alice", captor.getValue().getName());
@Mock and @InjectMocks are two key Mockito annotations that significantly reduce boilerplate code. @Mock creates a mock for a field, and @InjectMocks injects all mocks from the test class into the tested object via constructor, setter, or field.
The @InjectMocks mechanism attempts to inject dependencies in the following order: constructor with the most arguments, setter by type, private field. If none of these methods work, the object remains with null dependencies, and the test will fail with a NullPointerException.
It’s important to understand: @InjectMocks does not analyze field types — it substitutes any mock that is compatible by type. If a class has two fields of the same type, Mockito may inject the wrong mock. In such cases, it is recommended to use an explicit constructor with mock parameters.
In Android development, Mockito is used together with JUnit for testing ViewModel, Repository, and UseCase. Since these classes run on the JVM without the Android context, Mockito replaces their dependencies — Room DAO, Retrofit API, SharedPreferences — with stubs that have predictable behavior.
To add Mockito to an Android project, simply add the mockito-core or mockito-inline dependency (the latter supports mocking final classes and static methods). Version 5.12.0 (2024) includes Java 21 support and improved JUnit 5 integration.
// build.gradle.kts (module)
dependencies {
testImplementation("org.mockito:mockito-core:5.12.0")
testImplementation("org.mockito:mockito-junit-jupiter:5.12.0")
}
Previously, mocking static methods and constructors required PowerMock — an extension that worked through bytecode instrumentation. Starting with Mockito 5.x with mockito-inline, this capability is built-in directly: mockStatic(ClassName.class) allows mocking static methods without additional libraries.
A typical scenario: a ViewModel calls a repository method and transforms the result into UI state. Mockito replaces the repository, and the test checks that the ViewModel correctly handles both the success response and the error. When using the Clean Architecture, mocks are created for each layer: DataSource, Repository, and UseCase — this allows testing each layer in isolation.
Frequently Asked Questions
Mockito is a library for Java and Kotlin that uses proxies and reflection. MockK is a Kotlin-first library with support for coroutines, extension functions, and final classes without additional configuration.
Starting with Mockito 2.1, mocking final classes is supported via opt-in. In version 5.x (mockito-inline), this is enabled by default. Simply add the mockito-inline dependency and use the standard mock() method.
A Spy is a partial mock that by default calls real methods but allows overriding some of them via when().thenReturn(). Spy is useful for testing legacy code when you cannot rewrite the entire class.
thenReturn always returns the same value regardless of arguments. thenAnswer calculates the return value based on the invocation — call arguments, the mock itself, and state. For dynamic responses, always use thenAnswer.
Verify checks not only the result but also the process — the fact of accessing the dependency. This is critical for services that need to save data or send notifications. Without verify, the test will not detect that a method didn’t call save() or send().
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also