skip to content

@MockitoBean

@MockitoBean swaps a context bean for a Mockito mock you stub per test, and it changes the context cache key. Interviewers ask when mocking a bean is better than wiring the real one, and when it makes the test prove nothing.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

5

What is @MockitoBean and what problem does it solve in a Spring test?

level: juniorimportance: must knowfreq 45%

answer

  1. Spring 6.2, replaces Boot @MockBean
  2. swaps a context bean for a Mockito mock
  3. injected into the field too — when().thenReturn()
  4. @Mock alone is NOT in the context
  5. 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
java
@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

for a junior

Know it replaces a context bean with a mock and is stubbed with when().thenReturn().

for a middle

Know it succeeds Boot's @MockBean, resolves by type or name, and is reset between tests.

for a senior

Contrast it with @Mock and unit-testing, and note it forces the real context to load.

for a principal

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.

context

open as a page

How do you stub a @MockitoBean, and what happens to its stubs and recorded interactions between test methods?

level: middleimportance: must knowfreq 38%

basics

~10 s

Stub with Mockito: when(mock.method(args)).thenReturn(value) (or given(...).willReturn(...)). By default Spring resets the mock after each test method, so stubs and verify() history do not leak between tests.

open as a page

How does @MockitoBean affect the Spring TestContext context cache, and why can overusing it slow a test suite?

level: seniorimportance: should knowfreq 25%

basics

~20 s

The set of bean overrides is part of the context's cache key (MergedContextConfiguration). Two test classes with different @MockitoBean declarations get separate cached ApplicationContexts, so heavy or varied use causes many contexts to load — slower startup and more memory.

open as a page

How does @MockitoBean decide which bean to replace, and what do the name and enforceOverride attributes control?

level: seniorimportance: should knowfreq 20%

basics

~20 s

By default it matches the bean by the field's type. If several beans share that type you must set name (or value) to pick one. If no bean matches, it normally registers the mock as a new bean; enforceOverride = true instead requires an existing bean and fails otherwise.

open as a page

As a tech lead, when would you avoid @MockitoBean in favour of another testing approach, and how do you keep a large Spring suite fast?

level: principalimportance: nice to knowfreq 14%

basics

~20 s

Avoid @MockitoBean when a pure unit test (plain @Mock, no context) or a narrow slice test would do — it forces a full context and can fragment the context cache. Reserve it for integration tests that genuinely need real Spring wiring plus one faked collaborator.

open as a page