Spring Boot测试无法Mock MongoTemplate致MongoRepository空指针报错
报错具体成因
- 你当前使用的
@SpringBootTest会加载整个项目的全量Spring上下文,启动过程中会扫描到配置类上的@EnableMongoRepositories注解,自动为项目里所有MongoRepository接口(也就是报错提到的operacionesPendientesRepository)创建代理Bean实例。 - 这些Repository代理Bean的初始化逻辑,强依赖真实
MongoTemplate实例提供的数据库连接、实体映射解析能力,而你已经把容器内的真实MongoTemplate替换成了Mock对象,缺失必要的初始化逻辑,就会在Bean初始化阶段触发空指针,测试根本无法启动到你的业务方法执行阶段。 - 从测试目标来看,你本来只想对单个Service类的方法做单元测试,却加载了全链路的Spring上下文,引入了大量和测试目标无关的Bean初始化依赖,这是触发报错的核心原因。
可行解决方式
两种方案都不需要引入嵌入式Mongo数据库,完全通过Mock实现测试目标,也不会增加额外依赖:
方案1:采用纯Mockito单元测试模式(推荐,启动速度快)
完全剥离Spring容器加载流程,从根源上避开无关Bean的初始化:
- 移除测试类上所有需要加载Spring上下文的注解:
@SpringBootTest、@RunWith(SpringJUnit4ClassRunner.class)、@ActiveProfiles("test") - 直接使用Mockito原生的测试运行器,手动实例化被测的Service类,通过构造器传入Mock的
MongoTemplate实例,完全不走Spring Bean装配逻辑。 - 参考测试类写法:
@RunWith(MockitoJUnitRunner.class) public class MongoUpdateUtilityTest { @Mock private MongoTemplate mongoTemplate; // 手动初始化被测对象,不依赖Spring容器 private MongoUpdateUtility mongoUpdateUtility; @Before public void setup() { mongoUpdateUtility = new MongoUpdateUtilityImpl(mongoTemplate); } @Test public void updateOK1() { final Map<String, Object> map = new HashMap<>(); map.put("test", null); map.put("test2", "value"); when(mongoTemplate.updateFirst(Mockito.any(Query.class), Mockito.any(Update.class), Mockito.any(Class.class))) .thenReturn(null); when(mongoTemplate.findById(Mockito.anyString(), Mockito.any(Class.class))).thenReturn(null); assertNull(this.mongoUpdateUtility.update("2", map, Map.class)); } }
- 这种方式不会触发Spring扫描、初始化MongoRepository的流程,彻底规避之前的空指针报错,完全符合你仅需Mock测试Service逻辑的需求。
方案2:保留轻量Spring上下文,排除无关的Mongo自动配置
如果一定要走Spring容器的测试流程,就需要在启动时排除不需要的Mongo自动配置,阻止无关Repository Bean的初始化:
- 在
@SpringBootTest注解中添加配置,排除Mongo相关的自动装配类,避免触发Repository代理Bean的初始化逻辑 - 参考配置写法:
@SpringBootTest( classes = {}, exclude = { MongoRepositoriesAutoConfiguration.class, MongoDataAutoConfiguration.class } ) @RunWith(SpringJUnit4ClassRunner.class) @ActiveProfiles("test") public class MongoUpdateUtilityTest { // 原有Mock声明、测试逻辑保持不变 }
- 这种配置会阻止Spring扫描项目内的MongoRepository接口,也就不会触发之前因为Mock MongoTemplate导致的初始化空指针问题。
内容的提问来源于stack exchange,提问作者Wrong
相关产品推荐
相关产品推荐

