Spring Boot MockMvc测试@Transactional报错及MockBean模拟DAO失效咨询
问题1:@Transactional注解导致测试报错的兼容方案
报错的核心原因是测试类注解配置冲突,@WebMvcTest是Web层单测专用注解,只会加载Controller相关组件,不会初始化事务管理器、Service层的完整配置,触发@Transactional的切面逻辑时缺少依赖类和配置导致类加载失败。
调整方式如下:
- 优先修改抽象测试类注解,移除
@WebMvcTest:如果你是做全链路集成测试,将注解替换为@SpringBootTest(Spring Boot项目),确保你引入的product-application-context-test.xml中已经配置了HibernateTransactionManager和事务注解驱动<tx:annotation-driven/>,同时检查测试依赖中引入了对应版本的spring-orm包匹配你的Hibernate版本。 - 如果你不需要测试真实事务逻辑,可以直接在测试类中新增
@MockBean private PlatformTransactionManager transactionManager;,直接模拟事务管理器,就不会触发真实的事务初始化逻辑,无需修改业务代码的@Transactional注解。 - 也可以给测试类加上
@Transactional和@Rollback注解,使用Spring测试提供的事务管理器自动管理测试事务,执行完后自动回滚不污染数据。
问题2:@MockBean预设返回值不生效的解决方法
不生效的核心原因是上下文配置混乱导致Mock的DAO实例没有注入到Activator中,或者没有提前定义Mock的行为规则,调整方式如下:
- 先完成问题1中的上下文注解修正,移除
@WebMvcTest确保测试上下文统一,MockBean能被正确注入到Activator的依赖中。如果XML中也配置了ApplicantDAO的bean,给@MockBean加上@Primary注解,让Spring优先使用Mock实例。 - 在测试方法执行请求前,先定义MockDAO的返回规则,示例如下:
@Test public void testProdApp() throws Exception { // 提前定义Mock方法的返回值 ApplicantDTO expectReturn = new ApplicantDTO(); // 自定义expectReturn的属性值 when(applicantDAO.updateApp(any(ApplicantDTO.class))).thenReturn(expectReturn); // 再执行原有请求逻辑 ProdAppRequest appRequest = getProdAppRequest(); mvc.perform(post("/baseurl/applicant").headers(getHeaders()).accept(MediaType.APPLICATION_JSON) .content(mapToJson(appRequest)).contentType(MediaType.APPLICATION_JSON)).andDo(print()) .andExpect(status().isOk()); }
- 如果你使用
@SpyBean做部分模拟,需要用doReturn(expectReturn).when(applicantDAO).updateApp(any())的写法定义规则,避免先触发真实方法执行。
内容的提问来源于stack exchange,提问作者Pravin
相关产品推荐
相关产品推荐

