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.