使用Mockito when().thenReturn()打桩时出现NullPointerException问题排查
问题分析与解决
你遇到的NullPointerException是因为只Mock了BindingStubHelper,但没有Mock它返回的BindingStub对象。测试代码执行bindingStubHelper.getBindingStub()时,默认返回null,后续调用null.generatePayments()自然抛出空指针异常。
你的核心代码回顾
定义的接口
public interface BindingStubHelper { public BindingStub getBindingStub() throws java.rmi.RemoteException; }
实现类
@Configuration public class BindingStubImpl implements BindingStubHelper { @Value("${my.url}") private URL url; @Override public BindingStub getBindingStub() throws java.rmi.RemoteException { BindingStub BindingStub = new BindingStub(url, null); return BindingStub; } }
业务代码调用
@Autowired private BindingStubHelper bindingStub; ... payments = bindingStub.getBindingStub().generateSchedule(paymentRequest);
测试代码(存在问题的版本)
Payment payments = new Payment( 34.97, 22.58304, 0.0, 0.0, 534.97, 0, 0, 7.0, installmentList, 500, 500, 500, 500, 10, 500, 0.0, 20.00); PaymentRequest paymentRequest = new PaymentRequest( 500.0, startDate, renewalDate, Source.Annex, "838", "065714", "MQ", Type.New); when(bindingStubHelper .getBindingStub() .generatePayments(paymentRequest)) .thenReturn(payments);
修正后的测试代码
需要先MockBindingStub实例,让bindingStubHelper.getBindingStub()返回这个Mock对象,再对generatePayments方法进行Mock:
// 1. 先Mock BindingStub对象 BindingStub mockBindingStub = Mockito.mock(BindingStub.class); // 2. 指定BindingStubHelper返回这个Mock的BindingStub when(bindingStubHelper.getBindingStub()).thenReturn(mockBindingStub); // 3. 最后Mock generatePayments方法的返回结果 Payment payments = new Payment( 34.97, 22.58304, 0.0, 0.0, 534.97, 0, 0, 7.0, installmentList, 500, 500, 500, 500, 10, 500, 0.0, 20.00); PaymentRequest paymentRequest = new PaymentRequest( 500.0, startDate, renewalDate, Source.Annex, "838", "065714", "MQ", Type.New); when(mockBindingStub.generatePayments(paymentRequest)).thenReturn(payments);
简洁链式写法(可选)
如果追求代码简洁,也可以用链式调用完成:
when(bindingStubHelper.getBindingStub()).thenReturn(Mockito.mock(BindingStub.class)); when(bindingStubHelper.getBindingStub().generatePayments(paymentRequest)).thenReturn(payments);
不过分开定义Mock对象的方式更清晰,便于后续扩展测试逻辑。
内容的提问来源于stack exchange,提问作者runnerpaul
相关产品推荐
相关产品推荐

