MockBean
Spring Boot
Application Configuration
Unit Testing
Java Development

Configure MockBean component before application start

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

@MockBean replaces or adds a bean in the Spring test ApplicationContext before the context is fully used by the test. That is usually enough when you only need a mock during request handling or ordinary bean interaction. The tricky case is when startup logic uses that bean before your test method runs. Then the mock must not only exist early, it must also be preconfigured early.

What @MockBean Does

In Spring Boot tests, @MockBean registers a Mockito mock in the test context and replaces an existing bean of the same type if one exists. That means the mock is part of the context, not just a local test variable.

A standard pattern looks like this:

java
1@SpringBootTest
2class BillingServiceTest {
3
4    @MockBean
5    private ExchangeRateClient exchangeRateClient;
6
7    @Autowired
8    private BillingService billingService;
9
10    @Test
11    void calculatesInvoice() {
12        when(exchangeRateClient.fetchRate("USD")).thenReturn(new BigDecimal("1.10"));
13        // run test
14    }
15}

This works well when the bean is only called after the test starts.

Why Startup Logic Changes the Problem

Suppose the application calls the dependency during:

  • '@PostConstruct'
  • 'ApplicationRunner'
  • 'CommandLineRunner'
  • eager bean initialization

In that case, stubbing the mock in @BeforeEach or the test method is too late. The mock exists, but it still returns Mockito defaults during startup.

That can lead to:

  • 'null values where real data was expected'
  • context startup failures
  • confusing test behavior that looks like Spring timing issues

Use a Preconfigured Mock Bean

If startup code depends on the mock's behavior, define a test configuration that returns a pre-stubbed Mockito mock:

java
1import static org.mockito.Mockito.mock;
2import static org.mockito.Mockito.when;
3
4@SpringBootTest
5@Import(BillingServiceTest.TestConfig.class)
6class BillingServiceTest {
7
8    @TestConfiguration
9    static class TestConfig {
10        @Bean
11        @Primary
12        ExchangeRateClient exchangeRateClient() {
13            ExchangeRateClient client = mock(ExchangeRateClient.class);
14            when(client.fetchRate("USD")).thenReturn(new BigDecimal("1.10"));
15            return client;
16        }
17    }
18
19    @Autowired
20    private BillingService billingService;
21}

This works because the mock is already configured before dependent beans use it during context creation.

When @MockBean Is Still the Right Tool

If the dependency is not touched during startup, @MockBean is still simpler and usually preferred. It is concise, integrates cleanly with Spring Boot tests, and replaces the bean automatically.

For current Spring readers, there is one version note: newer Spring Framework testing support includes @MockitoBean, and current Spring Boot documentation marks @MockBean as deprecated in newer Boot lines. The underlying idea is the same: override a bean in the test context with a Mockito mock.

Alternative: Avoid Startup Work in the First Place

Sometimes the cleanest test fix is architectural. If a bean makes network calls or expensive operations during startup, ask whether that logic belongs there at all.

Moving the work out of @PostConstruct and into an explicit method often makes the application:

  • easier to test
  • easier to start locally
  • less fragile in production

Test problems around early mocking are often a signal that the application is doing too much at startup.

Common Pitfalls

The biggest mistake is stubbing a @MockBean in @BeforeEach and expecting that stub to influence application startup. By then, startup has already happened.

Another mistake is using @MockBean when a simple property override or fake bean would be clearer. Not every test problem needs Mockito.

A third issue is forgetting that context caching can change how test setup behaves across classes. Keep mock configuration explicit and local to the test slice you need.

Summary

  • '@MockBean registers a mock in the Spring test ApplicationContext.'
  • It is fine for normal test-time interactions, but startup logic can require earlier stubbing.
  • If a bean is called during context startup, prefer a preconfigured @TestConfiguration bean or equivalent override.
  • Newer Spring testing stacks also offer @MockitoBean for similar bean override behavior.
  • If startup mocking is painful, reconsider whether the application should perform that work during startup at all.

Course illustration
Course illustration

All Rights Reserved.