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

Java SpringBoot中如何Mock final类ServiceBusReceiverAsyncClient做单元测试?

解决ServiceBusReceiverAsyncClient(final类)的Mockito单元测试问题

方案一:启用Mockito MockMaker Inline

Mockito 2.x及以上版本支持mock final类,只需添加简单配置即可:

  • 在测试资源目录src/test/resources下创建mockito-extensions文件夹,新建文件org.mockito.plugins.MockMaker,内容写入:
mock-maker-inline

配置完成后,修正原有测试代码的语法错误即可正常运行:

@Mock
private ServiceBusReceiverFactory factory;

@Test
void test() {
    ServiceBusReceiverAsyncClient mockedReceiver = Mockito.mock(ServiceBusReceiverAsyncClient.class);
    when(this.factory.getClient()).thenReturn(mockedReceiver);
 
    consumer.listen(ack);
    // 触发ServiceBusReceiverAsyncClient.receivedMessages()调用,进而触发ack逻辑

    verify(ack, atLeastOnce()).success();
}

方案二:封装自定义接口隔离依赖

如果不想修改Mockito配置,可以通过封装接口的方式隔离对final类的直接依赖:

  1. 定义业务所需的接口:
public interface MessageReceiverClient {
    Flux<ServiceBusReceivedMessage> receivedMessages();
    // 按需添加其他业务需要调用的方法
}
  1. 实现类包装原ServiceBus客户端:
public class ServiceBusMessageReceiverClient implements MessageReceiverClient {
    private final ServiceBusReceiverAsyncClient client;

    public ServiceBusMessageReceiverClient(ServiceBusReceiverAsyncClient client) {
        this.client = client;
    }

    @Override
    public Flux<ServiceBusReceivedMessage> receivedMessages() {
        return client.receivedMessages();
    }
}
  1. 修改业务代码依赖MessageReceiverClient接口,测试时直接mock该接口:
@Mock
private ServiceBusReceiverFactory factory;
@Mock
private MessageReceiverClient mockedReceiver;

@Test
void test() {
    when(this.factory.getClient()).thenReturn(new ServiceBusMessageReceiverClient(Mockito.mock(ServiceBusReceiverAsyncClient.class)));
    when(mockedReceiver.receivedMessages()).thenReturn(Flux.just(new ServiceBusReceivedMessage(...))); // 模拟消息返回

    consumer.listen(ack);

    verify(ack, atLeastOnce()).success();
}

方案三:使用PowerMock(兼容旧版本,不推荐)

如果项目依赖的Mockito版本较低,可通过PowerMock实现final类的mock:

  1. 引入PowerMock相关依赖(根据Maven/Gradle调整)
  2. 测试类添加注解并编写测试:
@RunWith(PowerMockRunner.class)
@PrepareForTest(ServiceBusReceiverAsyncClient.class)
public class YourConsumerTest {
    @Mock
    private ServiceBusReceiverFactory factory;

    @Test
    void test() {
        ServiceBusReceiverAsyncClient mockedReceiver = PowerMockito.mock(ServiceBusReceiverAsyncClient.class);
        when(this.factory.getClient()).thenReturn(mockedReceiver);
 
        consumer.listen(ack);

        verify(ack, atLeastOnce()).success();
    }
}

内容的提问来源于stack exchange,提问作者Matheus Weber

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 17:06:12