Mock Static Method using JMockit

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.

Leave a Reply

Your email address will not be published.