如何使用Mockito拦截第三方库静态getInstance调用并返回模拟对象
结论
可以实现,不需要PowerMockito等额外静态测试工具,使用Mockito 3.4.0及以上版本自带的原生静态方法mock能力即可满足需求。如果无法升级Mockito版本,也可以通过包装类适配的方案解决。
方案1:使用Mockito原生静态mock(推荐)
前置依赖要求
- 确保项目引入的Mockito版本不低于3.4.0
- 额外引入
mockito-inline依赖(用于启用Inline Mock Maker能力,是Mockito实现静态方法mock的基础,不需要其他额外工具)
Maven依赖示例:
<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>4.11.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-inline</artifactId> <version>4.11.0</version> <scope>test</scope> </dependency>
测试代码示例
import org.mockito.MockedStatic; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.times; import static org.junit.jupiter.api.Assertions.assertEquals; @Test void testCreateInstance() { // 构造自定义返回的模拟对象 ThirdPartyLibraryFactory mockFactory = mock(ThirdPartyLibraryFactory.class); // 开启静态方法mock作用域,try-with-resources会自动关闭mock,不影响其他测试用例 try (MockedStatic<ThirdPartyLibrary> mockedStatic = mockStatic(ThirdPartyLibrary.class)) { // 定义静态方法调用的返回逻辑,匹配任意入参返回模拟对象 mockedStatic.when(() -> ThirdPartyLibrary.getInstance(any(), any())) .thenReturn(mockFactory); // 调用待测试的业务方法 ThirdPartyLibraryFactory result = YourClass.createInstance(); // 验证返回结果与预期一致 assertEquals(mockFactory, result); // 可选:验证静态方法的调用次数 mockedStatic.verify(() -> ThirdPartyLibrary.getInstance(any(), any()), times(1)); } }
方案2:包装类适配(适用于无法升级Mockito的场景)
如果项目无法升级Mockito到3.4.0以上版本,可以通过封装静态调用的方式绕开静态mock需求:
第一步:新增第三方库调用包装类
public class ThirdPartyLibraryWrapper { public ThirdPartyLibraryFactory getInstance(String param1, String param2) { return ThirdPartyLibrary.getInstance(param1, param2); } }
第二步:改造原有业务代码,依赖包装类实例
public class YourClass { private final ThirdPartyLibraryWrapper wrapper; // 构造注入包装类,生产环境传入new ThirdPartyLibraryWrapper(),测试传入mock对象 public YourClass(ThirdPartyLibraryWrapper wrapper) { this.wrapper = wrapper; } public ThirdPartyLibraryFactory createInstance() { return wrapper.getInstance(param1, param2); } }
第三步:测试代码示例
@Test void testCreateInstanceWithWrapper() { ThirdPartyLibraryWrapper mockWrapper = mock(ThirdPartyLibraryWrapper.class); ThirdPartyLibraryFactory mockFactory = mock(ThirdPartyLibraryFactory.class); when(mockWrapper.getInstance(any(), any())).thenReturn(mockFactory); YourClass yourClass = new YourClass(mockWrapper); ThirdPartyLibraryFactory result = yourClass.createInstance(); assertEquals(mockFactory, result); }
内容的提问来源于stack exchange,提问作者Niraj Chowdhary
相关产品推荐
相关产品推荐

