您的位置:

Mock静态方法完全指南

在编写程序的过程中,经常会用到静态方法。静态方法往往是一个固定的函数,可以直接通过类来调用,无需实例化对象。想要测试这类静态方法,却常常很难,因为不同的测试数据能够引起不同的结果。为了解决这个问题,我们就需要使用Mock静态方法来进行测试。下面,我们来详细介绍Mock静态方法的一些方面。

一、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 MockedStatic staticClassMock;

    @Parameterized.Parameters
    public static Collection
    data() {
        return Arrays.asList(new Object[][]{
                {1, 10},
                {2, 20},
                {3, 30}
        });
    }

    @Parameterized.Parameter(0)
    public int param1;

    @Parameterized.Parameter(1)
    public int param2;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testStaticMethods() {
        staticClassMock.when(() -> StaticClass.staticMethod1(param1)).thenReturn(param2);
        staticClassMock.when(() -> StaticClass.staticMethod2(param1)).thenReturn(param2);

        int result1 = StaticClass.staticMethod1(param1);
        int result2 = StaticClass.staticMethod2(param1);

        Assert.assertEquals(param2, result1);
        Assert.assertEquals(param2, result2);
    }
}

   
  

七、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静态方法提供帮助。
Mock静态方法完全指南

2023-05-23
印象笔记记录java学习(Java成长笔记)

2022-11-12
掌握 PowerMockito 静态方法

2023-05-22
java方法整理笔记(java总结)

2022-11-08
Mock模拟数据的全面解析

2023-05-20
java笔记,尚硅谷java笔记

2022-12-01
重学java笔记,java笔记总结

2022-11-23
java静态类,java静态类和静态方法

2023-01-05
jsp程序开发学习笔记2,jsp程序设计题库

本文目录一览: 1、《JSP&Servlet学习笔记》pdf下载在线阅读,求百度网盘云资源 2、林信良编著jsp&servlet学习笔记第2版课后答案吗 3、jsp有没有快速掌握的办法呀? 4、要学J

2023-12-08
全方位解析Mock服务

2023-05-20
Easy-Mock入门指南

2023-05-21
php生成全静态页面的方法,php生成静态html

2023-01-07
Mock测试详解

2023-05-18
Python开发网站的完整指南

一、Web框架 Python开发网站的第一步是选择一个Web框架。Python提供了许多Web框架,包括Django、Flask和Pyramid等。其中,Django是最受欢迎的Web框架,提供了一个

2023-12-08
Python开发网站的完整指南

一、Web框架 Python开发网站的第一步是选择一个Web框架。Python提供了许多Web框架,包括Django、Flask和Pyramid等。其中,Django是最受欢迎的Web框架,提供了一个

2023-12-08
Mock数据的意义与应用

2023-05-19
java学习笔记(java初学笔记)

2022-11-14
Windows静态路由完全指南

2023-05-16
前端mock详解

2023-05-23
Python Class的完整指南

2023-05-13