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

Java Mockito单元测试中服务调用返回null问题排查

问题结论

该问题完全是测试侧Mock配置及代码写法错误导致,和生产环境client服务的逻辑无关。其他开发人员正常调用是因为走的是真实client逻辑,没有走Mock桩逻辑。

具体根因排查
  • Mock实例不匹配:
    你在测试代码里手动mock了client实例,给它打了doReturn(res)的返回桩,但你没有把这个mock出来的client、或者你mock的clientFactory注入到被测类classAToTest中。被测类内部持有的client实例根本不是你打桩的这个对象,你配置的返回规则自然不会生效。
    另外你测试代码里打桩用的变量名是client,最后verify调用的却是creativeToolsClient,明显存在变量名混淆的问题,进一步说明你操作的mock对象和被测类实际持有的对象不是同一个。
  • @Mock注解未生效:
    你用@Mock注解标记了响应对象res,但从你贴的setUp代码看,你没有初始化Mockito注解:既没有加Mockito对应的Runner,也没有调用MockitoAnnotations.openMocks(this),这会导致res本身就是null,就算打桩生效,返回值也会是null。
  • 参数匹配不一致:
    你打桩时匹配的入参类型是ServiceProto.PutItemsRequest,但verify时用的入参类型是IngestionServiceProto.PutItemsRequest,如果这两个不是同一个类,参数匹配会直接失败,Mock不会触发你配置的返回规则。
  • 异常被吞干扰排查:
    你写了空的catch块捕获NullPointerException,异常发生时没有任何输出,根本看不到具体栈信息,会直接拖慢问题定位效率。
  • 业务代码存在语法问题:你贴的被测方法代码里,client.putItems(...)后多写了一个.build()调用,如果putItems本身返回的就是PutItemsResponse类型,多余的build调用要么编译失败,要么在putItems返回mock对象时触发空指针。
修复步骤
  • 初始化Mockito注解。在测试类上添加@RunWith(MockitoJUnitRunner.class),或者在setUp方法第一行加MockitoAnnotations.openMocks(this),保证@Mock标记的res对象被正常初始化,不是null。
  • 统一Mock实例,保证依赖注入正确。如果你是通过构造方法向ClassAToTest传依赖,new被测类实例时必须把你mock的client、clientFactory作为参数传入,不要让被测类内部自己初始化client;如果是注解注入依赖,用@InjectMocks注解标记被测类实例,自动注入mock对象。同时统一变量名,打桩和verify时操作同一个mock client对象,不要出现变量名混用的问题。
  • 统一参数匹配规则。确认putItems方法的入参类全限定名,打桩和verify时用相同的Request类型做匹配,避免因类型不匹配导致桩逻辑不触发。
  • 删掉空的catch块。测试阶段不要吞异常,方便出错时通过栈信息快速定位问题。
  • 检查被测方法代码,删掉putItems返回值后多余的.build()调用,保证业务代码逻辑正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 13:24:21