You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot从2.1升级到2.3后@MockBean对MyBatis仓库失效求助

Spring Boot 2.3升级后@MockBean对MyBatis Repository失效的解决办法

问题现象

将Spring Boot从2.1升级到2.3后,单元测试中用@MockBean模拟MyBatis的StockQuantityRepository时,服务类里注入的却是实际的代理实例($Proxy132),而非测试类中配置的Mock实例(StockQuantityRepository$MockitoMock$xxx),导致测试调用了真实数据库方法而失败,但@MockBean对Service、Controller等组件仍能正常工作。

测试类代码片段:

@MockBean
private StockQuantityRepository stockQuantityRepository;

Mockito.doReturn(lockedList)
       .when(stockQuantityRepository)
       .lockStockQuantityList(Mockito.anyList(), Mockito.anyInt()); 

服务类代码片段:

lockedStockList = stockQuantityRepository.lockStockQuantityList(processList, lockWaitTimeout); 

问题原因

Spring Boot 2.3调整了MyBatis自动配置的Bean注册逻辑,MyBatis的Mapper代理Bean通过MapperFactoryBean动态创建,其注册时机晚于@MockBean的Bean替换逻辑,导致实际的Mapper代理覆盖了Mock实例。

解决办法

方案1:给@MockBean添加@Primary注解

在测试类的MockBean上加上@Primary,确保Mock实例的优先级高于MyBatis自动创建的代理Bean:

@MockBean
@Primary
private StockQuantityRepository stockQuantityRepository;

// 原有Mock配置不变
Mockito.doReturn(lockedList)
       .when(stockQuantityRepository)
       .lockStockQuantityList(Mockito.anyList(), Mockito.anyInt()); 

方案2:手动创建MockBean并标记@Primary

如果方案1不生效,可通过@Bean方法手动创建Mock实例,强制让容器优先使用这个Mock:

@SpringBootTest
public class YourTestClass {

    @Autowired
    private StockQuantityRepository stockQuantityRepository;

    @Autowired
    private YourService yourService;

    @Bean
    @Primary
    public StockQuantityRepository stockQuantityRepository() {
        return Mockito.mock(StockQuantityRepository.class);
    }

    @BeforeEach
    void setUp() {
        Mockito.doReturn(lockedList)
               .when(stockQuantityRepository)
               .lockStockQuantityList(Mockito.anyList(), Mockito.anyInt()); 
    }
}

方案3:使用@MyBatisTest(仅针对MyBatis单测场景)

如果测试只关注MyBatis相关逻辑,用@MyBatisTest替代@SpringBootTest,该注解会自动禁用不必要的自动配置,同时正确处理MockBean:

@MyBatisTest
public class StockQuantityRepositoryTest {

    @MockBean
    private StockQuantityRepository stockQuantityRepository;

    @Autowired
    private YourService yourService;

    @Test
    void testLockStock() {
        Mockito.doReturn(lockedList)
               .when(stockQuantityRepository)
               .lockStockQuantityList(Mockito.anyList(), Mockito.anyInt()); 

        // 执行测试逻辑
        yourService.processStock();

        // 验证调用
        Mockito.verify(stockQuantityRepository).lockStockQuantityList(Mockito.anyList(), Mockito.anyInt());
    }
}

方案4:检查Mapper扫描配置

如果项目中自定义了@MapperScan注解,确保扫描路径正确,且没有和Spring Boot的自动配置冲突。避免在测试类中重复配置Mapper扫描,防止重复创建Bean。

内容的提问来源于stack exchange,提问作者Sandeep Kumar P K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 20:20:11