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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:13:07