Replacing Deprecated @MockBeans in Spring Boot 3.4+
Problem Statement
Since Spring Boot 3.4.0, the @MockBean and @MockBeans annotations have been deprecated in favor of the new @MockitoBean annotation. This change affects developers who use these annotations to create custom meta-annotations for group mocking multiple dependencies in tests.
The challenge arises when migrating existing compositions like:
@MockBeans({
@MockBean(ServiceA.class),
@MockBean(ServiceB.class),
@MockBean(ServiceC.class)
})Without a direct @MockitoBeans replacement, developers with numerous mocks (20+) face tedious manual declarations in each test class.
Solution
With Spring Boot 3.4+, replace class-level @MockBeans with @MockitoBean using its types attribute to specify multiple beans. This approach maintains the grouped mocking behavior while using the new annotation system.
Migration Steps
- Replace
@MockBeanswith@MockitoBean - Convert individual
@MockBeanentries to thetypesarray - Update package imports
Here's how to rewrite the custom annotation:
import org.springframework.test.context.bean.override.mockito.MockitoBean;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
// Old approach: @MockBeans({@MockBean(ServiceA.class), ...})
@MockitoBean(types = {ServiceA.class, ServiceB.class, ServiceC.class})
public @interface MyMocksTest {
}Field-Level Migration
For individual field mocks:
// Old: @MockBean
@MockitoBean
private ServiceA serviceA;
// Spy beans replacement
@MockitoSpyBean // Replaces @SpyBean
private ServiceB serviceB;Key Differences Explained
- Class-Level Support:
@MockitoBean(types = {...})replaces the deprecated@MockBeanscontainer - Repeatable Annotation:
@MockitoBeancan be repeated at type level instead of using a container:java@MockitoBean(ServiceA.class) @MockitoBean(ServiceB.class) public @interface MyMocksTest {} - New Location: Import from
org.springframework.test.context.bean.override.mockito - Same Behavior: Null returns for unstubbed methods and automatic application context integration remain unchanged
Compatibility Note
While deprecated annotations remain functional until Spring Boot 3.5, migrating avoids technical debt
Additional Recommendations
- Group Common Mocks: Organize mock definitions by module or functionalityjava
@MockitoBean(types = {PaymentService.class, InvoiceService.class}) public @interface FinancialMocks {} - Custom Qualifiers: For beans needing qualification, use
nameattribute:java@MockitoBean(value = "mainDataSource", types = DataSource.class) - Annotation Composition: Combine with other test annotations:java
@SpringBootTest @MyMocksTest @ActiveProfiles("test") public class MyIntegrationTest { ... }
Conclusion
Migrating from deprecated @MockBeans to @MockitoBean is straightforward using the types attribute for class-level definitions. This approach maintains test conciseness while adopting Spring Boot 3.4+'s improved mocking strategy. Implement these changes before the deprecated annotations are removed in future versions.