Static methods are part of a class and are not linked to any specific object. They are commonly used for tasks like computing values in utility classes, logging system events, or retrieving configuration properties. However, static methods are difficult to test as they can’t be overridden and often interact with external systems.
To solve this, Mockito allows you to mock static methods and control their behavior and makes tests more reliable. Before Mockito 3.4.0, developers had to rely on external tools like PowerMock to achieve this. With the introduction of mockStatic, Mockito now provides built-in support for mocking static methods.
This article highlights how to mock static methods using Mockito, the setup process, and different methods.
Understanding Mocking Static Methods
Static methods belong to a class rather than an object, meaning their behavior is fixed and shared across all instances. This makes testing static methods difficult, as Mockito was not originally designed to mock them.
However, testing static methods is required in many cases. For instance, in Android unit testing, a user might want to mock static methods to isolate tests from other parts of the application or give different return values without executing the actual static method logic.
To achieve this, Mockito offers several methods. Here is a detailed breakdown of the different ways to mock static methods.
- Using Mockito’s mockStatic(): Mockito provides the mockStatic() method to override the behavior of static methods during a test temporarily. This is achieved using a MockedStatic object, which allows defining specific behavior for a static method within a controlled scope.
- Verifying Static Method Calls: Mockito allows verifying static method calls to confirm whether a specific method is executed during a test. This is useful in scenarios where test correctness depends on a static method being called.
- Mocking Static Methods with Arguments: Some static methods require specific arguments to match the mock configuration, especially when handling file operations, network calls, or external services. If a static method should throw an exception for invalid inputs, Mockito Throw Exception (thenThrow()) can be used to mock this behavior. This helps test how the system handles failures without triggering real exceptions.
- Using PowerMock for Legacy Static Methods: Projects using older versions of Mockito (before 3.4.0) use PowerMock to mock static methods. PowerMock provides deep mocking capabilities by allowing developers to override static method behaviors even when Mockito cannot. However, PowerMock requires additional setup and adds complexity compared to modern Mockito features.
Follow-Up Read: Unit Testing: A Detailed Guide
Why Should You Implement Mocking Static Methods?
Mocking static methods improves the flexibility and maintainability of the tests. Here are some situations where mocking static methods can help:
- Preventing unintended execution: Mocking avoids calling actual static methods and prevents unexpected side effects when dealing with utility classes.
- Isolating Dependencies: Static methods that write to a database or interact with a file system can cause unexpected issues. Mocking separates testing from these external systems.
- Controlling Method Outputs: Static methods that perform calculations or return specific results can be mocked to return expected values for test cases.
Read More: Java Debugging Tools and Techniques
How to set up the mockStatic feature?
Here’s how to set up mock static methods in Mockito.
- Mockito 3.x (Before Version 5): Mocking static methods were not natively supported in Mockito 3.4.0 and earlier. To work on this, you can use additional libraries like PowerMock or design wrappers for static methods to mock them.
- Mockito 5.x and Later: Mockito 5.x and later provide built-in mockStatic support and enable you to mock static methods directly in your tests without additional setup.
Example:
Imagine you want to test a feature without running the actual code inside a static method. This example shows how to temporarily replace that method’s behavior with a fixed response during testing.
try (MockedStatic<MyUtilityClass> mocked = Mockito.mockStatic(MyUtilityClass.class)) { mocked.when(() -> MyUtilityClass.staticMethod()).thenReturn("Mocked Value"); }
Output:
How to Create a Simple Utility Class?
Here’s a simple utility class that contains static methods:
public class MyUtilityClass { public static String staticMethod() { return “Original Static Value”; } public static String staticMethodWithArgs(String name) { return “Hello, “ + name; } }
Output:
This utility class has two static methods. The first method returns a simple string, and the second method takes an argument and returns a simple greeting message.
How to mock the behavior of Static Methods?
There are two types of static method behavior that you can mock using Mockito.
Static Method Mocking: With and Without Arguments
- With Arguments: The method returns different values based on input and is useful for testing how the method responds to dynamic inputs without running actual code.
- Without Arguments: The method always returns the same value and is useful for testing fixed behavior without running actual code.
Here is how you can mock these behaviors.
1. Mocked Method with No Argument
To mock a static method with no arguments, use the following code:
import static org.mockito.Mockito.*; public class StaticMethodMockingTest { @Test void testMockStaticMethodWithoutArguments() { try (MockedStatic<MyUtilityClass> mocked = mockStatic(MyUtilityClass.class)) { mocked.when(MyUtilityClass: : staticMethod).thenReturn(“Mocked Value”); // Assert the mocked return value assertEquals(“Mocked Value”, MyUtilityClass.staticMethod()); } } }
Standard Output:
Console Output with JUnit:
2. Mocked Method with One or More Arguments
The process is similar to static methods that accept one or more arguments. Here’s an example of mocking the method that accepts a parameter:
@Test void testMockStaticMethodWithArguments() { try (MockedStatic<MyUtilityClass> mocked = mockStatic(MyUtilityClass.class)) { mocked.when(() -> MyUtilityClass.staticMethodWithArgs(“Alice”)).thenReturn(“Mocked Hello, Alice”); // Assert the mocked return value assertEquals(“Mocked Hello, Alice”, MyUtilityClass.staticMethodWithArgs(“Alice”)); } }
Standard Output:
Console Output with JUnit:
Read More: Unit Testing in Java with JUnit
How to Verify Method Call?
Once a static method is mocked, a user might want to verify whether it was called during the test. Mockito allows us to do this through the ‘verify’ method.
Here’s how to verify that a static method was called:
@Test void testVerifyStaticMethodCall() { try (MockedStatic<MyUtilityClass> mocked = mockStatic(MyUtilityClass.class)) { MyUtilityClass.staticMethod(); mocked.verify(MyUtilityClass: : staticMethod); } }
Output:
Mocking Static Methods with Mockito: 3 Ways to Do It
There are several ways to mock static methods using Mockito. Some of the common methods are:
Option #1: Create Wrapper Objects
Wrapping static methods inside instance methods makes mocking easier. This allows users to mock the wrapper instance directly instead of using static methods.
public class StaticWrapper { public String callStaticMethod() { return MyUtilityClass.staticMethod(); } } @Test void testUsingWrapper() { StaticWrapper wrapper = mock(StaticWrapper.class); when(wrapper.callStaticMethod()).thenReturn(“Mocked Value”); assertEquals(“Mocked Value”, wrapper.callStaticMethod()); }
Output:
Option #2: Use PowerMock
PowerMock is a popular tool for mocking static methods. It extends Mockito’s behavior to support static method mocking.
Here’s a quick example of using PowerMock to mock a static method:
import static org.mockito.Mockito.*; import org.junit.Test; import static org.junit.Assert.assertEquals; import org.powermock.api.mockito.PowerMockito; import org.junit.runner.RunWith; import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.core.classloader.annotations.PrepareForTest; @RunWith(PowerMockRunner.class) @PrepareForTest(MyUtilityClass.class) public class PowerMockExample { @Test public void testStaticMethodMocking() { PowerMockito.mockStatic(MyUtilityClass.class); PowerMockito.when(MyUtilityClass.staticMethod()).thenReturn(“Mocked Value”); // Assert the mocked return value assertEquals(“Mocked Value”, MuUtilityClass.staticMethod()); } }
Output:
Option #3: Just Vanilla Mockito
Starting from Mockito 3.4.0, mocking static methods no longer requires external dependencies. As shown earlier, the mockStatic feature allows users to mock static methods efficiently.
@Test void testMockStaticMethodUsingMockito() { try (MockedStatic<MyUtilityClass> mocked = mockStatic(MyUtilityClass.class)) { mocked.when(MyUtilityClass: :staticMethod).thenReturn(“Mocked Value”); assertEquals(“Mocked Value”, MyUtilityClass.staticMethod()); } }
Standard Output:
Console Output with JUnit:
Conclusion
The mockStatic method provides a simple way to mock static methods in unit tests. However, for older versions of Mockito, extensions like PowerMock or wrapping static methods are still feasible alternatives.
To improve the quality of testing, use a real-device testing platform like BrowserStack Automate. It lets you automate tests across different devices, browsers, and OS configurations without managing complex setups.