What is @MockitoBean and what problem does it solve in a Spring test?
answer
- Spring 6.2, replaces Boot @MockBean
- swaps a context bean for a Mockito mock
- injected into the field too — when().thenReturn()
- @Mock alone is NOT in the context
- reset between test methods (MockReset.AFTER)
basics
~10 s@MockitoBean (Spring 6.2) is a test-field annotation that replaces a real bean in the loaded Spring ApplicationContext with a Mockito mock, so collaborators receive the fake and you control its behaviour with when(...).thenReturn(...).
solid answer
~40 s@MockitoBean is a Spring Framework 6.2 test annotation (package org.springframework.test.context.bean.override.mockito) placed on a field of a @SpringBootTest / @ExtendWith(SpringExtension) test. It is the framework successor to Spring Boot's now-deprecated @MockBean. When the context loads, the bean-override machinery finds the matching bean (by type, or by the name attribute) and swaps it for a Mockito mock; that same mock is also injected into the annotated field so you can stub it with when(mock.call()).thenReturn(x) and later verify(mock). Any other bean that autowires that dependency gets the mock instead of the real implementation — perfect for isolating a slow, remote, or nondeterministic collaborator (a payment gateway, an email sender) while still testing through the real Spring wiring. Unstubbed methods return Mockito defaults (null, 0, empty).
code
java · 19 lines@SpringBootTest
class OrderServiceTest {
@MockitoBean
PaymentGateway paymentGateway; // replaces the real bean in the context
@Autowired
OrderService orderService; // gets the mock injected for PaymentGateway
@Test
void placesOrderWhenPaymentApproved() {
when(paymentGateway.charge(any())).thenReturn(ChargeResult.approved());
Order order = orderService.place(new Cart(/* ... */));
assertThat(order.status()).isEqualTo(Status.PAID);
verify(paymentGateway).charge(any());
}
}go deeper
Know it replaces a context bean with a mock and is stubbed with when().thenReturn().
Know it succeeds Boot's @MockBean, resolves by type or name, and is reset between tests.
Contrast it with @Mock and unit-testing, and note it forces the real context to load.
Weigh it against slice tests / pure unit tests for suite speed and context reuse.
## What it is `@MockitoBean` is an annotation added in **Spring Framework 6.2** as part of the TestContext Framework's *Bean Override* feature. Fully qualified: `org.springframework.test.context.bean.override.mockito.MockitoBean`. It is the **core-framework replacement for Spring Boot's `@MockBean`** (`org.springframework.boot.test.mock.mockito.MockBean`), which is deprecated as of Spring Boot 3.4. Because it now lives in the framework's `spring-test` module, it works in any Spring test — you no longer need Spring Boot. ## The problem it solves In an integration test you load a real `ApplicationContext` (via `@SpringBootTest`, `@WebMvcTest`, `@ExtendWith(SpringExtension.class)`, etc.). Some bean in that context is undesirable to exercise for real — it calls a remote API, sends email, is slow, or is nondeterministic. Plain Mockito's `@Mock` creates a mock **object** but does *not* put it into the Spring context, so any bean autowiring that dependency still gets the real one. `@MockitoBean` bridges that gap: it **removes the real bean and registers a Mockito mock in its place**, and injects the same mock into your test field. ## How it resolves which bean to replace - **By type (default):** the field's declared type is used. If exactly one bean of that type exists, it is replaced. - **By name:** set `@MockitoBean(name = "...")` (or `value`) when there are multiple candidates of the type, or to target a specific bean. - If **no** matching bean exists, by default `@MockitoBean` *creates a new bean* (the mock is added). Set `enforceOverride = true` to require that an original bean already exists (fails fast otherwise). - Can also be declared at **class level** with a `types` attribute to mock several types without one field each. ## Stubbing and defaults You drive the mock with standard Mockito: `when(repo.findById(1L)).thenReturn(Optional.of(entity));` or BDD style `given(...).willReturn(...)`. **Unstubbed** methods return Mockito's defaults — `null` for objects, `0`/`false` for primitives, empty collections/`Optional.empty()` for those return types. ## Reset between tests Spring registers `MockitoResetTestExecutionListener`, which **resets the mock between test methods** (default `MockReset.AFTER`). So stubs and recorded interactions do **not** leak from one `@Test` to the next — each method starts clean. ## Related annotations - `@MockitoSpyBean` — wraps the *real* bean in a Mockito spy (real methods run unless stubbed); replaces Boot's `@SpyBean`. ## When to use it Use it for integration/slice tests where you want the real Spring wiring but need to isolate one collaborator. For pure unit tests of a single class, prefer constructing the class with plain Mockito `@Mock` collaborators and **no** Spring context at all — that is faster.
- How is @MockitoBean different from Mockito's plain @Mock?@Mock just creates a mock object in your test; it is not registered in the Spring context, so autowired collaborators still receive the real bean. @MockitoBean actually replaces the bean inside the ApplicationContext, so everything that depends on it gets the mock.
- What does a @MockitoBean return for a method you never stubbed?Mockito's default answer: null for object returns, 0/false for primitives, and empty collections / Optional.empty() for those types.
saying these in an interview costs you the question
- Thinking @Mock and @MockitoBean are interchangeable (the plain @Mock is never placed in the Spring context).
- Believing stubs persist across test methods (they are reset by default, MockReset.AFTER).
- Claiming @MockitoBean is a Spring Boot-only annotation — it is core Spring Framework 6.2.