Mock Static Method using JMockit – 使用JMockit模拟静态方法

最后修改: 2018年 8月 20日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Some popular mocking libraries such as Mockito and Easymock generate mock-ups by taking advantage of Java’s inheritance-based class model. EasyMock implements an interface at runtime, whereas Mockito inherits from the target class to create a mocking stub.

一些流行的嘲讽库,如Mockito 和 Easymock,通过利用 Java 基于继承的类模型来生成嘲讽。EasyMock在运行时实现一个接口,而Mockito从目标类继承来创建一个嘲弄存根。

Neither approach works well for static methods since static methods are associated with a class and cannot be overridden. However, JMockit does provide a static method mocking features.

这两种方法都不能很好地适用于静态方法,因为静态方法是与类相关联的,不能被重写。然而,JMockit确实提供了一个静态方法嘲弄功能。

In this tutorial, we’ll explore some of these features.

在本教程中,我们将探讨这些功能中的一些。

For an introduction to JMockit, please see our previous article.

关于JMockit的介绍,请参见我们的前文

2. Maven Dependencies

2.Maven的依赖性

Let’s start with Maven dependencies:

让我们从Maven的依赖性开始。

<dependency>
    <groupId>org.jmockit</groupId>
    <artifactId>jmockit</artifactId>
    <version>1.24</version>
    <scope>test</scope>
</dependency>

You can find the latest versions of these libraries on Maven Central.

您可以在Maven Central上找到这些库的最新版本。

3. Static Method Called from Non-Static Method 

3.从非静态方法中调用静态方法

First, let’s consider a case when we have a class with a non-static method that internally depends upon static method:

首先,让我们考虑这样一种情况:一个具有非静态方法的类在内部依赖于静态方法

public class AppManager {

    public boolean managerResponse(String question) {
        return AppManager.isResponsePositive(question);
    }

    public static boolean isResponsePositive(String value) {
        if (value == null) {
            return false;
        }
        int length = value.length();
        int randomNumber = randomNumber();
        return length == randomNumber ? true : false;
    }

    private static int randomNumber() {
        return new Random().nextInt(7);
    }
}

Now, we want to test the method managerResponse(). Since its return value depends on another method we need to mock the isResponsePositive() method.

现在,我们要测试managerResponse()方法。因为它的返回值取决于另一个方法,我们需要模拟isResponsePositive()方法。

We can mock this static method using JMockit’s anonymous class mockit.MockUp.MockUp<T> (where T will be the class name) and @Mock annotation:

我们可以使用JMockit的匿名类mockit.MockUp.MockUp<T>其中T将是类名)和@Mock注释来模拟这个静态方法。

@Test
public void givenAppManager_whenStaticMethodCalled_thenValidateExpectedResponse() {
    new MockUp<AppManager>() {
        @Mock
        public boolean isResponsePositive(String value) {
            return false;
        }
    };

    assertFalse(appManager.managerResponse("Some string..."));
}

Here, we are mocking the isResponsePositive() with a return value that we would like to use for the test. Therefore, verifying the expected result using Assertions utility available in Junit-5.

在这里,我们正在模拟isResponsePositive()的返回值,我们希望将其用于测试。因此,使用Junit-5中的Assertions工具验证预期结果。

4. Test Private Static Method

4.测试私有静态方法

In a few cases, other methods use private static methods of the class:

在少数情况下,其他方法使用类的私有静态方法。

private static Integer stringToInteger(String num) {
    return Integer.parseInt(num);
}

For testing such method, we’d need to mock private static method. We can use the Deencapsulation.invoke() utility method provided by JMockit:

为了测试这种方法,我们需要模拟私有静态方法。我们可以使用由JMockit提供的Deencapsulation.invoke()实用方法。

@Test
public void givenAppManager_whenPrivateStaticMethod_thenValidateExpectedResponse() {
    int response = Deencapsulation.invoke(AppManager.class, "stringToInteger", "110");
    assertEquals(110, response);
}

As the name suggests, it’s purpose is to de-encapsulate the state of an object. In this way, JMockit simplifies testing methods that could not be tested otherwise.

顾名思义,它的目的是去封装一个对象的状态。通过这种方式,JMockit简化了测试方法,否则就无法进行测试。

5. Conclusion

5.结论

In this article, we have seen how static methods can be mocked using JMockit. For a more in-depth look at some of the advanced features of JMockit, take a look at our JMockit Advanced Usage article.

在这篇文章中,我们已经看到了如何使用JMockit来模拟静态方法。要更深入地了解JMockit的一些高级功能,请看我们的JMockit高级用法文章

As usual, the full source code for this tutorial is available over on GitHub.

像往常一样,本教程的完整源代码可在GitHub上获得