Mockito.when返回Null问题:CrossSellOffersServiceAdapter测试异常
看起来你遇到的Mock返回null问题,主要是由Mock对象类型不匹配和测试参数顺序错误这两个核心问题导致的,我帮你拆解并给出修复方案:
1. 最关键的问题:Mock对象类型不匹配
你的CrossSellOffersServiceAdapter类中注入的依赖是CrossSellOffersConnectBDS类型,但在测试类里Mock的却是CrossSellOffersConnectBDSAdapter类型。Mockito无法将错误类型的Mock对象注入到目标类中,导致实际调用的crossSellOffersConnectBDS根本不是你配置的Mock实例,自然返回默认的null。
修复方式:
把测试类中的Mock对象类型改成和Adapter类中依赖一致的类型:
@Mock private CrossSellOffersConnectBDS crossSellOffersConnectBDS; // 修正为与Adapter中一致的接口/类类型
2. 测试调用的参数顺序错误
先看getApplicableOffers的方法定义:
public Offers getApplicableOffers(String channelId, String customerId, String cinSuffix, String countryCode, String interactionPoint, String sessionId, Integer numberOfOffers)
参数顺序是:channelId → customerId → cinSuffix → countryCode → interactionPoint → sessionId → numberOfOffers
但你的测试调用是:
Offers offers = crossSellOffersService.getApplicableOffers("MBSG", "IBOXS007", "00", "SG","NEW_CC_ADDON", "S9718016D", 1);
这里把customerId和sessionId完全搞反了!你Mock的是getBDSCustomerInfo("MBSG", "S9718016D", "00", "SG"),但实际调用时传入的customerId是"IBOXS007",和Mock的参数不匹配,Mockito自然返回默认的null。
修复方式:
调整测试调用的参数顺序,严格匹配方法定义:
Offers offers = crossSellOffersService.getApplicableOffers("MBSG", "S9718016D", "00", "SG","NEW_CC_ADDON", "IBOXS007", 1);
3. 额外优化:Mock返回对象与后续参数一致性问题
你MockgetBDSCustomerInfo时返回的是sampleBDSResponse(),但后续MockgetCMPOffers时用的是bdsResponse这个Mock对象,这两个不是同一个实例。如果getCMPOffers依赖传入的bdsCustomerHoldings的属性,会导致这个Mock也不生效。
修复方式二选一:
- 让
sampleBDSResponse()直接返回bdsResponse这个Mock对象:Mockito.when(crossSellOffersConnectBDS.getBDSCustomerInfo("MBSG", "S9718016D", "00", "SG")).thenReturn(bdsResponse); - 或者用Mockito的匹配器,允许匹配任意
BDSCustomerHoldings实例:Mockito.when(crossSellOffersConnectCMP.getCMPOffers(any(BDSCustomerHoldings.class), eq("NEW_CC_ADDON"), eq("IBOXS007"), eq(1))) .thenReturn(CrossSellOffersConnectCMPAdapterTest.sampleCMPOffer());
完整修复后的测试类示例
别忘了添加Mock初始化的逻辑(要么用@Before,要么用MockitoJUnitRunner),否则@Mock和@InjectMocks不会生效:
public class CrossSellOffersServiceAdapterTest { @InjectMocks private CrossSellOffersServiceAdapter crossSellOffersService; @Mock private CrossSellOffersConnectBDS crossSellOffersConnectBDS; @Mock private CrossSellOffersConnectCMP crossSellOffersConnectCMP; @Mock private RestTemplate restTemplate; @Mock OffersRequest offersRq; @Mock private BDSRequest bdsRequest ; @Mock private BDSCustomerHoldings bdsResponse; @Before public void setUp() { MockitoAnnotations.openMocks(this); // 初始化所有Mock对象 } @Test public void getApplicableOffersTest() throws CrossSellOffersException { // Mock BDS调用,返回预设的bdsResponse Mockito.when(crossSellOffersConnectBDS.getBDSCustomerInfo("MBSG", "S9718016D", "00", "SG")) .thenReturn(bdsResponse); // Mock CMP调用 Mockito.when(crossSellOffersConnectCMP.getCMPOffers(bdsResponse, "NEW_CC_ADDON", "IBOXS007", 1)) .thenReturn(CrossSellOffersConnectCMPAdapterTest.sampleCMPOffer()); // 修正参数顺序后的调用 Offers offers = crossSellOffersService.getApplicableOffers("MBSG", "S9718016D", "00", "SG","NEW_CC_ADDON", "IBOXS007", 1); assertNotNull(offers, "response is not null"); } }
内容的提问来源于stack exchange,提问作者durgaPrasad

