SpringBoot2.7@WebMvcTest单元测试报错:需sqlSessionFactory/sqlSessionTemplate
解决SpringBoot 2.7中@WebMvcTest加载无关Bean导致的ApplicationContext初始化失败问题
问题根源
@WebMvcTest默认会扫描当前测试类所在包及其子包下的所有@Controller、@RestController类型组件。如果你的PaymentController和DemoApiController处于同一包结构下,测试启动时Spring上下文会自动加载DemoApiController,进而触发它的依赖链(DemoServiceImpl、DemoDataReadMapper)。而单元测试场景未配置MyBatis的sqlSessionFactory等核心组件,最终导致Mapper初始化失败。
解决方案
1. 明确指定@WebMvcTest仅加载目标控制器
直接在@WebMvcTest注解中指定要测试的PaymentController,让Spring上下文只初始化该控制器及其关联的MockBean,避免扫描无关组件:
@WebMvcTest(PaymentController.class) public class PaymentControllerTest { @MockBean private PaymentService paymentService; // 测试方法... }
2. Mock掉无关依赖或排除无关组件
如果需要保留部分全局配置,但要避免加载Demo相关的Bean,可以通过以下两种方式:
- Mock依赖链中的关键Bean:直接用
@MockBean模拟DemoDataReadMapper或DemoServiceImpl,阻断MyBatis初始化流程:@WebMvcTest(PaymentController.class) @MockBean({DemoDataReadMapper.class, DemoServiceImpl.class}) public class PaymentControllerTest { @MockBean private PaymentService paymentService; // 测试方法... } - 排除无关控制器:通过
excludeFilters排除DemoApiController的扫描:@WebMvcTest( controllers = PaymentController.class, excludeFilters = @ComponentScan.Filter( type = FilterType.ASSIGNABLE_TYPE, classes = DemoApiController.class ) ) public class PaymentControllerTest { @MockBean private PaymentService paymentService; // 测试方法... }
3. 按业务模块拆分包结构
从根源上避免扫描冲突,将不同业务的控制器拆分到独立包中(比如com.example.payment.controller、com.example.demo.controller),然后通过basePackages指定测试仅扫描目标模块的控制器:
@WebMvcTest(basePackages = "com.example.payment.controller") public class PaymentControllerTest { @MockBean private PaymentService paymentService; // 测试方法... }
内容的提问来源于stack exchange,提问作者OTUser
相关产品推荐
相关产品推荐

