如何用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
相关产品推荐
相关产品推荐

