
Spring Boot 3.1 默认禁用对具体类(非接口)的 @MockBean 自动代理,需显式启用 Mockito 的 mock-maker-inline 才能正确模拟 final 类、private 方法或普通 class 类型 Bean。
spring boot 3.1 默认禁用对具体类(非接口)的 `@mockbean` 自动代理,需显式启用 mockito 的 `mock-maker-inline` 才能正确模拟 `final` 类、`private` 方法或普通 `class` 类型 bean。
在 Spring Boot 3.1 中,@MockBean 对接口(如 AuthorizationManager)仍可正常工作,但对具体类(如 AuditService2)默认失效——这是因为 Spring Boot 3.1 升级至 Mockito 4+ 后,默认使用 mockito-core 的 default mock maker,该实现无法对非接口类型(尤其是含 final 方法或被 final 修饰的类)进行运行时字节码增强。而 AuthorizationManager 是接口,无需字节码修改即可代理;AuditService2 是普通 class,必须依赖 mock-maker-inline(基于 Byte Buddy 的 inline mock maker)才能生成真实 mock 实例。
✅ 解决方案:启用 mock-maker-inline
在测试类路径下(如 src/test/resources/mockito-extensions/)创建文件:
src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
文件内容仅一行:
mock-maker-inline
⚠️ 注意事项:
- 不要添加
.txt后缀,文件名必须严格为org.mockito.plugins.MockMaker; - 确保
mockito-inline依赖已声明(Spring Boot 3.1+ 的spring-boot-starter-test已包含,无需额外引入); - 若项目使用 Gradle,可验证依赖树:
./gradlew testCompileClasspath --configuration testCompileClasspath | grep mockito-inline; -
@MockBean注入后,务必通过Mockito.when(...).thenReturn(...)显式定义行为,否则调用将返回默认值(如0、null、false),而非抛出异常——这容易造成“看似注入成功,实则未生效”的假象。
? 示例修复后的测试片段:
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
public class ATestClass {
@MockBean private AuditService2 auditEventService2;
@MockBean private AuthorizationManager authorizationManager;
@Test
void getEvents() {
// ✅ 必须显式 stub 方法行为,否则 sumar() 将返回默认 int 值 0
when(auditEventService2.sumar(1, 2)).thenReturn(100);
int result = auditEventService2.sumar(1, 2);
assertEquals(100, result); // 通过
}
}
? 总结:Spring Boot 3.1 并非“不支持”对类使用 @MockBean,而是将 mock 能力交由底层 Mockito 的插件机制控制。启用 mock-maker-inline 是兼容旧版(SB 2.x)行为的关键一步,同时强化了测试的明确性与可控性——所有 mock 行为都需主动声明,避免隐式依赖。











