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

如何用Mockito验证Fluent API调用?当前写法抛出空指针异常

Mockito验证Fluent API调用的正确姿势(避免空指针异常)

你直接把链式调用写在verify里会触发空指针,核心原因是:Mockito创建的mock对象,默认所有方法调用都会返回null。当你调用verify(utils).newCharge()后,newCharge()返回的是null,后续再调用.withPay()自然就会抛出NPE。

要验证Fluent API的完整链式调用,得先让每个中间方法调用都返回有效的mock对象,再分别验证每一步的调用。下面是两种常用解决方案:

方案1:手动mock每个中间对象并设置返回值

假设你的Fluent API基于Builder模式,比如newCharge()返回ChargeBuilder实例,且每个withXXX()方法都返回ChargeBuilder自身。可以这么做:

// 1. mock Builder类
ChargeBuilder chargeBuilderMock = mock(ChargeBuilder.class);

// 2. 让每个链式方法返回自身,保证调用链不中断
when(chargeBuilderMock.withPay()).thenReturn(chargeBuilderMock);
when(chargeBuilderMock.withChargeType(anyString())).thenReturn(chargeBuilderMock);
when(chargeBuilderMock.withAmount(anyDouble())).thenReturn(chargeBuilderMock);
when(chargeBuilderMock.withCurrency(anyString())).thenReturn(chargeBuilderMock);

// 3. 让utils的newCharge()返回这个mock Builder
when(utils.newCharge()).thenReturn(chargeBuilderMock);

// 执行你的业务逻辑代码...

// 4. 分别验证每一步调用
verify(utils).newCharge();
verify(chargeBuilderMock).withPay();
verify(chargeBuilderMock).withChargeType("Commission");
verify(chargeBuilderMock).withAmount(1.1);
verify(chargeBuilderMock).withCurrency("USD");
verify(chargeBuilderMock).create();

方案2:使用Mockito的RETURNS_SELF默认答案

如果你的Builder类所有withXXX()方法都返回自身,可以用RETURNS_SELF简化配置,它会让mock对象的同类型返回方法自动返回自身:

// 创建mock时指定默认答案为RETURNS_SELF
ChargeBuilder chargeBuilderMock = mock(ChargeBuilder.class, Mockito.RETURNS_SELF);

// 设置utils.newCharge()返回该mock
when(utils.newCharge()).thenReturn(chargeBuilderMock);

// 执行业务逻辑...

// 同样分别验证每一步调用
verify(utils).newCharge();
verify(chargeBuilderMock).withPay();
verify(chargeBuilderMock).withChargeType("Commission");
verify(chargeBuilderMock).withAmount(1.1);
verify(chargeBuilderMock).withCurrency("USD");
verify(chargeBuilderMock).create();

特殊情况处理

如果Fluent API中不同方法返回不同类型的对象(比如withPay()返回PaymentBuilder,而非原来的ChargeBuilder),那需要分别mock每个类型的对象,并依次设置返回关系:

ChargeBuilder chargeBuilderMock = mock(ChargeBuilder.class);
PaymentBuilder paymentBuilderMock = mock(PaymentBuilder.class, Mockito.RETURNS_SELF);

// 设置chargeBuilder的withPay()返回paymentBuilder
when(chargeBuilderMock.withPay()).thenReturn(paymentBuilderMock);
// 根据API结构补充paymentBuilder后续方法的返回配置
// ...

when(utils.newCharge()).thenReturn(chargeBuilderMock);

// 验证时对应到各自的mock对象
verify(utils).newCharge();
verify(chargeBuilderMock).withPay();
verify(paymentBuilderMock).withChargeType("Commission");
// ...其他验证步骤

内容的提问来源于stack exchange,提问作者Jakub Znamenáček

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 03:10:23