This is a personal note that I decided to share. It reflects my understanding of a subject and may contain errors and approximations. Feel free to contribute by contacting me here. Any help will be credited!
Since Spring Boot 3.4.0, @MockBean
and @SpyBean
annotations in spring-boot-test
are deprecated (#39860). In favor of @MockitoBean
and @MockitoSpyBean
annotations from spring-test
.
Bean Overriding in Tests
The Spring team discourages developers from using bean overriding. In Spring Boot 2.1, Bean overriding has been disabled by default. However, in integration tests, developers may need to override some beans in the ApplicationContext
, either to mock them or to provide a different implementation.
In Spring Framework 6.2, they implemented a mechanism to override beans in integration tests.
Two implementations of this bean overriding mechanism are provided:
- A generic
@TestBean
annotation that allows the override of a bean with a static 0-argument factory method. - A Mockito-based implementation with two annotations
@MockitoBean
and@MockitoSpyBean
.
The bean override mechanism can be extended with custom implementations (as explained at the end of this blog post).
@MockitoBean and @MockitoSpyBean
The two annotations will replace @MockBean
and @SpyBean
. However, they do not provide the same features.
For example :
@MockitoBean
is not supported on@Configuration
class unlike@MockBean
(#33934).@MockitoBean
is not supported in@Component
class unlike@MockBean
(#34415).
However, the Spring team continues to improve the new annotations with existing @MockBean
features. For example, they added @Primary
support (#33819), class-level @MockitoBean
support (#33925)…
Both annotation sets rely on BeanFactoryPostProcessor
to register and replace bean definitions in the spring context.
@MockBean
and @SpyBean
, the new annotations modify the ApplicationContext
to override beans. Thus, there has been no improvement in the context’s cache management. Spring context cannot be cached between tests that don’t share the same mocks.Conclusion
Spring now offers a proper, extensible, and unified way of overriding beans in tests directly in the Spring framework.
As explained by the team, @MockitoBean
and @MockitoSpyBean
are not a “simple 1-1 replacement” for @MockBean
and @SpyBean
. While differences remain, the Spring team has actively incorporated community feedback enhancing the new annotations.
References
- Spring.io - Spring Framework 6.2.0-M1: Overriding Beans in Tests
- Github - Spring Boot @MockBean and @SpyBean deprecate
- Github - Issue on @MockitoBean not supported on @Configuration`
- Github - Spring Boot 2.1 Bean Overriding disabled by default
- Github - Test Bean Overrides do not honor
@Primary
semantics - Github - Support
@MockitoBean
at the type level on test classes - Github -
@MockitoBean
is not supported in@Component
class like@MockBean
is - Filip Procházka - Spring’s @MockBean is an anti-pattern