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
@TestBeanannotation that allows the override of a bean with a static 0-argument factory method. - A Mockito-based implementation with two annotations
@MockitoBeanand@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 :
@MockitoBeanis not supported on@Configurationclass unlike@MockBean(#33934).@MockitoBeanis not supported in@Componentclass 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
@Primarysemantics - Github - Support
@MockitoBeanat the type level on test classes - Github -
@MockitoBeanis not supported in@Componentclass like@MockBeanis - Filip Procházka - Spring’s @MockBean is an anti-pattern