一、Mock静态方法复原
在使用Mock静态方法的时候,有时候我们需要复原某个静态方法的方法体,让它返回真实的结果。这时候我们可以使用PowerMockito.mockStatic方法,将静态方法mock,然后使用PowerMockito.when()方法来指定其返回值。下面是使用PowerMockito.mockStatic方法的示例代码:
public class StaticClass { public static int staticMethod() { return 1; } } @RunWith(PowerMockRunner.class) @PrepareForTest(StaticClass.class) public class StaticClassTest { @Test public void testStaticMethod() { PowerMockito.mockStatic(StaticClass.class); PowerMockito.when(StaticClass.staticMethod()).thenReturn(2); Assert.assertEquals(2, StaticClass.staticMethod()); } }
上述代码中,我们使用了PowerMockito.mockStatic方法来mock了StaticClass类的静态方法。然后我们使用PowerMockito.when()方法指定其返回值为2。最后我们判断其返回值是否为2。因为复原了静态方法的方法体,因此实际上返回的是真实的结果,并不是我们mock的结果。
二、Mock静态方法无返回值
有时候,被测试的静态方法并没有返回值。这时候我们可以使用PowerMockito.doNothing()方法来指定其无返回值。下面是使用PowerMockito.doNothing()方法的示例代码:
@RunWith(PowerMockRunner.class) @PrepareForTest(StaticClass.class) public class StaticClassTest { @Test public void testDoNothingStaticMethod() { PowerMockito.mockStatic(StaticClass.class); PowerMockito.doNothing().when(StaticClass.class); StaticClass.staticMethod(); StaticClass.staticMethod(); Assert.assertTrue(true); } }
上述代码中,我们使用PowerMockito.doNothing()方法指定StaticClass类的静态方法无返回值。然后我们连续调用了两次静态方法,最终判断其返回值是否为true,来验证其无异常。
三、Mock静态方法不生效
有些时候,我们使用Mock静态方法时会出现问题,导致mock并没有生效。这时候,我们需要检查一下是否有以下情况:
1、是否使用了PowerMockRunner类作为测试类的运行器;
2、是否使用了PrepareForTest注解,指定要mock的静态方法所在的类;
3、是否添加了对应的Mock库依赖;
4、是否在mock前调用了PowerMockito.mockStatic方法;
5、是否使用了正确的Mockito/PowerMockito的静态方法。
同时,我们也可以打开PowerMock的调试日志来帮助我们排除问题。下面是开启调试日志的代码:
org.apache.log4j.BasicConfigurator.configure(); Logger.getRootLogger().setLevel(Level.DEBUG);
四、Mock静态方法void
有些时候,我们需要mock带有void返回值的静态方法。在这种情况下,我们需要使用PowerMockito.doNothing()方法来mock,具体的方法如下示:
@RunWith(PowerMockRunner.class) @PrepareForTest(StaticClass.class) public class StaticClassTest { @Test public void testStaticMethodWithVoidReturnType() { PowerMockito.mockStatic(StaticClass.class); PowerMockito.doNothing().when(StaticClass.class); StaticClass.staticMethodWithVoidReturnType(); Assert.assertTrue(true); } }
五、Mock静态方法并发
当一个方法被多次调用时,它可能会获取它所需要的资源并改变其状态,这可能会导致并发问题。在这种情况下,我们需要mock静态方法来控制其并发行为。使用PowerMockito.doAnswer方法来模拟静态方法的行为。
@RunWith(PowerMockRunner.class) @PrepareForTest(StaticClass.class) public class StaticClassTest { @Test public void testStaticMethodConcurrency() throws Exception { PowerMockito.mockStatic(StaticClass.class); PowerMockito.doAnswer(invocation -> { Thread.sleep(2000); return 1; }).when(StaticClass.class); StaticClass.staticMethod(); Assert.assertTrue(true); } }
六、静态方法Mock测试
有时候我们需要测试一个类中的多个静态方法。这时候我们可以使用Junit的Parameterized和Mockito的MockitoAnnotations来进行测试。下面是测试多个静态方法的示例代码:
@RunWith(Parameterized.class) public class StaticClassTest { @Mock private MockedStaticstaticClassMock; @Parameterized.Parameters public static Collection
七、mockup静态方法
在Java 9之前,我们可以使用MockUp类来mock静态方法。下面是使用MockUp类来mock静态方法的示例代码:
@RunWith(PowerMockRunner.class) @PrepareForTest(StaticClass.class) public class StaticClassTest { @Test public void testStaticMethodWithMockUp() { new MockUp() { @Mock public int staticMethod() { return 2; } }; Assert.assertEquals(2, StaticClass.staticMethod()); } }
八、Mockito静态方法
Mockito 3.4.0之后新增了Static方法的Mock,可以直接使用Mockito来Mock静态方法。使用Mockito来Mock静态方法只需要按照标准的Mockito的风格来实现即可。下面是使用Mockito来Mock静态方法的示例代码:
@RunWith(MockitoJUnitRunner.class) public class StaticClassTest { @Test public void testStaticMethod() { Mockito.mockStatic(StaticClass.class); Mockito.when(StaticClass.staticMethod()).thenReturn(2); Assert.assertEquals(2, StaticClass.staticMethod()); } }
九、Mock私有方法
Mock私有方法和Mock静态方法的方式类似,只不过我们需要使用PowerMockito.spy方法来mock私有方法。下面是使用PowerMockito.spy来mock私有方法的示例代码:
@RunWith(PowerMockRunner.class) @PrepareForTest(StaticClass.class) public class StaticClassTest { @Test public void testPrivateMethod() throws Exception { StaticClass sc = PowerMockito.spy(new StaticClass()); PowerMockito.doReturn(2).when(sc, "privateMethod"); Integer result = (Integer) Whitebox.invokeMethod(sc, "privateMethod"); Assert.assertEquals(2, result.intValue()); } }
十、Mock静态对象选取
当进行静态方法Mock测试时,我们有两种选取静态对象的方式,一种是Mock静态方法所在的类,另一种是Mock静态方法的调用出的对象。我们需要根据测试需要来选择对应的方式。
@RunWith(MockitoJUnitRunner.class) public class StaticClassTest { @Test public void testStaticMethod() { Mockito.mockStatic(StaticClass.class); Mockito.when(StaticClass.staticMethod()).thenReturn(2); // 选取类的方式 Assert.assertEquals(2, StaticClass.staticMethod()); // 选取调用静态方法的实例对象的方式 StaticClass sc = new StaticClass(); Assert.assertEquals(2, sc.staticMethod()); } }本篇文章介绍了Mock静态方法的几个方面,包括如何复原静态方法的方法体、Mock静态方法无返回值、Mock静态方法不生效、Mock静态方法void、Mock静态方法并发、静态方法Mock测试、mockup静态方法、Mockito静态方法、Mock私有方法、Mock静态对象选取等等。希望能够对大家使用Mock静态方法提供帮助。