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类的直接依赖:
- 定义业务所需的接口:
public interface MessageReceiverClient { Flux<ServiceBusReceivedMessage> receivedMessages(); // 按需添加其他业务需要调用的方法 }
- 实现类包装原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(); } }
- 修改业务代码依赖
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:
- 引入PowerMock相关依赖(根据Maven/Gradle调整)
- 测试类添加注解并编写测试:
@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
相关产品推荐
相关产品推荐

