@MockBean and @MockitoBean in Spring Testing

`@MockBean` and `@MockitoBean` let Spring tests replace or add beans in the application context with Mockito-based test doubles. They are useful when the class under test depends on collaborators that you want to control or isolate.

A Mockito mock is an object whose behavior is controlled by the test rather than by the real implementation. In a Spring test, a mock must also be available as a bean if the class under test receives that dependency through Spring dependency injection. These annotations bridge those two concerns.

`@MockBean` is the older Spring Boot testing annotation commonly used to register a Mockito mock in the test `ApplicationContext`. If a matching bean already exists, the mock can replace it; otherwise, Spring can add the mock as a bean. This allows other Spring-managed objects to receive the mock through normal dependency injection.

`@MockitoBean` is the Spring Framework annotation intended for Mockito-based bean overriding in tests. It provides the same general testing idea while moving the feature into the Spring Framework itself. When working on a project, use the annotation supported by that project's Spring and Spring Boot versions rather than assuming both are interchangeable in every setup.

The mock only replaces the Spring-managed dependency; it does not automatically define useful behavior. Use Mockito operations such as `when(...).thenReturn(...)` to stub calls and `verify(...)` to check interactions. This makes tests deterministic and avoids invoking external systems or complex collaborator logic.

Key points

Interview questions

What problem does `@MockBean` solve in a Spring test?

It lets a test put a Mockito mock into the Spring application context. This means Spring-managed classes can receive the mock through dependency injection instead of receiving the real implementation. The test can then stub the dependency and isolate the behavior of the component being tested.

What is the difference between `@Mock` and `@MockBean`?

`@Mock` creates a Mockito mock but does not register it as a Spring bean. `@MockBean` integrates the mock with the Spring test application context. Therefore, a Spring-managed object can automatically receive an `@MockBean` through dependency injection. `@Mock` is generally more appropriate for a pure Mockito unit test without a Spring context.

What does `@MockitoBean` do?

`@MockitoBean` tells Spring to use a Mockito mock as a bean in the test context. It can override an existing matching bean or contribute a mock bean when appropriate. This allows Spring-managed dependencies to be replaced while the test exercises the surrounding application wiring.

Why might a test using `@MockBean` still behave unexpectedly?

The mock only controls calls that actually reach that mock instance. A common problem is stubbing the wrong method, argument, or bean, especially when several beans have similar types or qualifiers. Another issue is accidentally testing the mock rather than the real component that should consume it. It is also important to check the project's Spring and Spring Boot versions because annotation behavior and availability can differ across versions.

When would you prefer a pure Mockito unit test over `@MockBean`?

A pure Mockito test is often appropriate when the behavior can be tested without Spring's application context. It usually starts faster and makes the unit's dependencies explicit. A Spring test with a mock bean is useful when the test needs actual Spring wiring, configuration, validation, or other context-managed behavior while replacing a particular collaborator. The choice should follow the behavior being tested rather than a blanket preference for one style.