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

Mockito模拟RestTemplate单元测试返回null触发NPE问题排查

问题核心原因
  • 测试框架注解冲突,两套体系不兼容
    你在JUnit4测试类上同时标注了@RunWith(MockitoJUnitRunner.class)和@SpringBootTest。JUnit4的运行逻辑完全以@RunWith指定的Runner为准,MockitoJUnitRunner会全程接管测试流程,根本不会触发Spring相关的测试初始化逻辑——哪怕写了@SpringBootTest,也不会加载任何Spring上下文,整个测试本质是纯Mockito单元测试。
  • 对Mock对象缺失必要的方法打桩,导致执行流提前中断
    你只通过@Mock生成了EmailForwardConfig的Mock实例并注入到Controller中,但从来没有给这个Mock的getUrl()方法配置返回规则。Mockito对未打桩的方法默认返回空值:String类型返回null,引用类型返回null。
    这也是为什么Mockito会提示restTemplate零交互的原因:代码在执行到emailConfig.getUrl()这步时,要么因为emailConfig未注入(也就是你说的移除@Mock后对象为null的场景)触发NPE,要么执行流因为其他配置问题在这里中断,根本走不到调用restTemplate.postForEntity()的环节,自然不会和这个Mock对象产生任何交互,你看到的ResponseEntity为null的现象,本质是代码没走到那一步的表现,不是RestTemplate Mock返回了null。
  • 打桩和断言逻辑不匹配,全流程跑通后也会测试失败
    你给RestTemplate打桩返回的响应体是小写字符串"done",但测试断言里校验的是大写的"Done",就算全流程正常执行,这个字符串相等断言也会失败。
修正操作步骤
  1. 明确测试类型,消除框架冲突
    根据你要写的测试类型二选一,不要混用注解:
    • 纯单元测试场景:移除@SpringBootTest注解,保留MockitoJUnitRunner,所有依赖通过Mockito的@Mock、@InjectMocks完成模拟
    • Spring集成测试场景:把测试运行器替换为SpringRunner.class,使用@MockBean注解替换Spring容器中的RestTemplate、EmailForwardConfig Bean,不能用普通的@Mock
  2. 补全缺失的打桩逻辑
    在测试方法或者@Before的setup方法中,给EmailForwardConfig的getUrl方法配置固定返回值,比如:
    Mockito.when(emailConfig.getUrl()).thenReturn("http://test-mail-server/");
    
    这一步会避免未打桩返回null导致的执行中断。
  3. 统一打桩和断言的匹配规则
    校准打桩的返回值和断言的校验值,比如把两边的字符串都统一为"done",避免大小写不匹配导致的断言失败。
  4. 确认打桩的执行顺序
    所有Mockito的打桩逻辑,必须放在调用Controller接口方法之前执行,不能颠倒顺序。

按照上面的步骤调整后,再运行测试,就能看到RestTemplate的Mock对象正常被调用,不会再出现ResponseEntity为null的空指针问题。

内容的提问来源于stack exchange,提问作者kfersch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 13:15:05