如何为静态类的testAble()编写单元测试并mock同类静态方法?
解决静态方法Mock的几种方案
Mockito核心版本确实不支持静态方法Mock,但有几种可行的解决路径:
方案1:使用Mockito Inline扩展(推荐)
从Mockito 3.4.0开始,官方提供了mockito-inline扩展来支持静态方法Mock,无需额外引入PowerMock这类第三方库。
步骤:
- 确保测试依赖中包含
mockito-inline(可替换原有的mockito-core,或同时引入) - 用
Mockito.mockStatic()静态Mock目标类,在try-with-resources块中执行测试逻辑,确保Mock自动清理。
测试代码示例:
import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mockStatic; public class MyClassTest { @Test void testTestAbleWhenSomethingReturnsHello() { // 静态Mock MyClass类 try (var mockedStatic = mockStatic(MyClass.class)) { // 指定something()方法的返回值 mockedStatic.when(MyClass::something).thenReturn("Hello"); // 调用待测试方法 String result = MyClass.testAble(); // 断言结果 assertEquals("Wow", result); } } @Test void testTestAbleWhenSomethingReturnsOtherValue() { try (var mockedStatic = mockStatic(MyClass.class)) { mockedStatic.when(MyClass::something).thenReturn("Hi"); String result = MyClass.testAble(); assertEquals("LoL", result); } } }
方案2:重构代码解耦静态依赖(更优的长期方案)
静态方法会拉高代码耦合度,导致测试困难。若允许修改原代码,建议重构解耦:
重构思路:
把something()的逻辑提取到单独类中,让MyClass依赖该类实例(或通过静态setter替换实例,方便测试)。
重构后的代码:
// 提取的逻辑类 public class SomethingProvider { public String getSomething() { return "Hello"; } } // 修改后的MyClass public class MyClass { // 可通过静态setter替换实例,用于测试 private static SomethingProvider provider = new SomethingProvider(); public static void setProvider(SomethingProvider provider) { MyClass.provider = provider; } public static String something() { return provider.getSomething(); } public static String testAble() { if (something().equals("Hello")) { return "Wow"; } return "LoL"; } }
测试代码(用普通Mockito即可):
import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class MyClassTest { @Test void testTestAbleWhenSomethingReturnsHello() { // Mock依赖类 SomethingProvider mockProvider = mock(SomethingProvider.class); when(mockProvider.getSomething()).thenReturn("Hello"); // 替换MyClass中的provider MyClass.setProvider(mockProvider); String result = MyClass.testAble(); assertEquals("Wow", result); } }
这种方案从根源解决了静态方法难测试的问题,让代码更具扩展性和可测试性。
方案3:使用PowerMock(兼容旧版本Mockito)
若项目无法升级到支持静态Mock的Mockito版本,可使用PowerMock实现静态方法Mock。但注意PowerMock会修改类加载机制,可能与部分测试框架或工具存在兼容性问题。
测试代码示例:
import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import static org.junit.Assert.assertEquals; @RunWith(PowerMockRunner.class) @PrepareForTest(MyClass.class) // 指定需要Mock的静态类 public class MyClassTest { @Test void testTestAble() { // Mock静态方法something() PowerMockito.mockStatic(MyClass.class); PowerMockito.when(MyClass.something()).thenReturn("Hello"); String result = MyClass.testAble(); assertEquals("Wow", result); } }
需引入powermock-module-junit4和powermock-api-mockito2相关依赖。
内容的提问来源于stack exchange,提问作者Gul Ahmed
相关产品推荐
相关产品推荐

