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

如何用Mockito Mock方法内新建的MqttWrapper对象(无需PowerMockito)

解决方案

核心思路

利用Mockito 3.5+提供的MockedConstruction拦截所有new MqttWrapper()的调用并生成Mock实例,同时捕获这些实例,用于后续的方法Stub和调用验证。

修改后的测试代码

try(MockedConstruction<MqttWrapper> mockedMqttWrapper = mockConstruction(MqttWrapper.class)){
    // 准备依赖Mock
    mockMethodCalls();
    
    // 获取生产代码中会创建的MqttWrapper Mock实例(仅创建一个,取列表第一个)
    MqttWrapper mockMqttWrapper = mockedMqttWrapper.constructed().get(0);
    
    // Stub getMqttClientConnection方法,匹配捕获到的Mock实例
    doReturn(mqttClientConnection).when(mqttClientConnectionManager)
        .getMqttClientConnection(mockMqttWrapper);
    
    // 执行测试方法
    mqttWrapperFactoryImpl = spy(new MqttWrapperFactoryImpl(context));
    outputMqttWrapper = mqttWrapperFactoryImpl.getMqttWrapperForSiteId(SITE_ID);
    
    // 断言返回的实例就是Mock对象
    assertEquals(mockMqttWrapper, outputMqttWrapper);
    
    // 验证getMqttClientConnection的调用次数和参数
    verify(mqttClientConnectionManager, times(1))
        .getMqttClientConnection(mockMqttWrapper);
    verifyNoMoreInteractions(mqttClientConnectionManager);
}

关键说明

  • mockedMqttWrapper.constructed()会返回所有通过new MqttWrapper()创建的Mock实例列表,生产代码仅创建一个,直接取索引0即可。
  • Stub和验证时必须使用捕获到的Mock实例作为参数匹配条件,确保逻辑严谨性;若无需精确匹配,也可使用any(MqttWrapper.class)替代。
  • 确保Mockito版本在3.5以上,MockedConstruction是该版本新增特性。

额外优化方案

若createNewMqttWrapperInstance逻辑复杂,可将MqttWrapper的创建逻辑抽为独立protected方法:

protected MqttWrapper createMqttWrapper() {
    return new MqttWrapper();
}

测试时通过Spy Stub该方法,直接返回预先创建的Mock实例:

MqttWrapper mockMqttWrapper = mock(MqttWrapper.class);
mqttWrapperFactoryImpl = spy(new MqttWrapperFactoryImpl(context));
doReturn(mockMqttWrapper).when(mqttWrapperFactoryImpl).createMqttWrapper();

// 后续Stub、执行、验证逻辑与上述一致

内容的提问来源于stack exchange,提问作者piyush bansal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 11:56:35