Mock Void类型Rest接口时返回Null问题排查求助
我来帮你一步步排查这个Mock失效的问题——你遇到的返回Null情况,大概率是Mock匹配条件未命中或者RestTemplate实例未正确注入导致的,下面是具体的分析和解决步骤:
1. 最可能的原因:匹配类型不匹配
你的原方法调用是void.class,但Mock里写的是Void.class——这两个是完全不同的类型!void.class代表的是无返回值的原始类型,而Void.class是它的包装类,Mockito的匹配器会严格校验类型,所以这会直接导致匹配失败,找不到对应的Stub,自然返回Null。
修正后的Mock代码
把Matchers.eq(Void.class)改成Matchers.eq(void.class)(或者等价的Void.TYPE):
Mockito.when(restTemplate.exchange( Matchers.any(), Matchers.eq(HttpMethod.PUT), Matchers.any(HttpEntity.class), Matchers.eq(void.class) // 这里改成void.class )).thenReturn(new ResponseEntity<>(HttpStatus.ACCEPTED));
2. 确认RestTemplate实例是否被正确Mock
如果你的被测试类里是自己new了RestTemplate,而不是通过依赖注入获取Mock实例,那你写的Mock逻辑根本不会生效——Mockito只能Mock你创建的实例,无法替换类内部new出来的对象。
正确的Mock注入方式
确保测试类里的RestTemplate是通过@Mock创建,并注入到被测试Bean中:
@ExtendWith(MockitoExtension.class) public class YourServiceTest { @Mock private RestTemplate restTemplate; // Mock的实例 @InjectMocks private YourService yourService; // 被测试类,依赖RestTemplate }
3. 检查Matchers的导入和版本
如果你用的是Mockito 3.x及以上版本,推荐使用org.mockito.ArgumentMatchers替代旧的org.mockito.Matchers,避免因导入错误导致匹配逻辑异常。
4. 模拟抛出异常的正确写法
如果你想让Mock调用抛出异常,不要用when(...).thenReturn()的写法,应该用doThrow()——因为如果匹配条件不命中,when会尝试执行真实方法,可能引发NPE:
Mockito.doThrow(new RuntimeException("Mocked error")) .when(restTemplate) .exchange( Matchers.any(), Matchers.eq(HttpMethod.PUT), Matchers.any(HttpEntity.class), Matchers.eq(void.class) );
5. 验证Mock是否被调用
可以在测试结束后添加验证,确认RestTemplate的exchange方法是否真的被触发,以此排查是不是调用路径的问题:
Mockito.verify(restTemplate, Mockito.times(1)) .exchange( Matchers.any(), Matchers.eq(HttpMethod.PUT), Matchers.any(HttpEntity.class), Matchers.eq(void.class) );
如果验证失败,说明你的测试代码根本没走到这个Mock方法调用,那自然不会返回你设置的响应。
内容的提问来源于stack exchange,提问作者avi

