Mockito Mock Creation

Mockito creates configurable test doubles that let you isolate a class from its dependencies. A mock can return stubbed values and record interactions so tests can verify how the class under test uses its collaborators.

A Mockito mock is an object generated for a type, typically an interface or class, whose behavior can be controlled during a unit test. The most direct API is `Mockito.mock(Type.class)`, while `@Mock` provides annotation-based creation when the test is configured to initialize Mockito annotations.

By default, an unstubbed mock does not execute the real dependency behavior. Mockito supplies default return values appropriate to the return type, such as `null` for reference types and zero-like values for primitive types. You can define specific behavior with `when(...).thenReturn(...)` or related stubbing APIs.

Mocks also record method calls. Verification such as `verify(repository).findById(42L)` checks that the class under test interacted with its dependency as expected. This makes mocks useful for testing collaboration and control flow rather than the real implementation of the dependency.

For annotation-based mocks, `@Mock` must be initialized by Mockito's test integration, such as a Mockito JUnit 5 extension. Without initialization, the annotated field is not automatically a usable mock. The exact setup depends on the test framework and Mockito integration being used.

Key points

Interview questions

How do you create a mock with Mockito?

The direct API is `Mockito.mock(MyType.class)`. Mockito returns a test double whose behavior can be configured with stubbing. If using annotations, `@Mock` can create the field when Mockito's test integration initializes it. The choice is mainly between explicit creation and annotation-based test setup.

What is the difference between stubbing and verification?

Stubbing specifies what a mock should return or do when a particular call occurs. For example, `when(repository.findName(42L)).thenReturn("Ada")` defines the response. Verification checks whether an interaction happened, such as `verify(repository).findName(42L)`. They test different aspects: behavior supplied by the dependency versus interaction performed by the code under test.

What happens if you call an unstubbed method on a Mockito mock?

Mockito normally returns a default value rather than calling the real implementation. For reference-returning methods this commonly means `null`, while primitive return types receive their corresponding default value. Collections and some other types can receive Mockito-provided defaults depending on configuration and Mockito behavior. Tests should explicitly stub values that are important to the scenario rather than relying on accidental defaults.

How does `@Mock` differ from `Mockito.mock()`?

Both can produce Mockito mock objects, but they differ in how the mock is created and initialized. `Mockito.mock()` creates the object explicitly at the point of the call. `@Mock` declares a field and relies on Mockito's test integration to initialize it, for example through the JUnit 5 Mockito extension. Annotation-based setup can make tests less repetitive, while explicit creation makes the construction point obvious.

Why might a backend unit test use a Mockito mock instead of a real repository?

A repository mock can isolate the service from the database and make the test deterministic and fast. The test can prescribe repository responses and verify that the service requests the expected data. This focuses the test on the service's behavior rather than database connectivity or query correctness. Integration tests can separately exercise the real repository and database interaction.