1. Overview
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.
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.
In this tutorial, we’ll explore some of these features.
For an introduction to JMockit, please see our previous article.
2. Maven Dependencies
Let’s start with Maven dependencies:
<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.
3. Static Method Called from Non-Static Method
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.
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:
@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.
4. Test Private Static Method
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:
@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.
5. Conclusion
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.
As usual, the full source code for this tutorial is available over on GitHub.