Home Arrow Icon Knowledge base Arrow Icon Global Arrow Icon Can you provide an example of mocking a static method with PowerMock and Mockito


Can you provide an example of mocking a static method with PowerMock and Mockito


Mocking static methods in Java can be achieved using PowerMock, which extends the capabilities of Mockito. Here's a detailed example of how to mock a static method using both PowerMock and Mockito:

Using PowerMock with EasyMock

First, let's consider an example where we have a class `IdGenerator` with a static method `generateNewId()` that we want to mock. This method is used by another class, `ServiceRegistrator`.

java
public class IdGenerator {
    public static long generateNewId() {
        return System.currentTimeMillis();
    }
}

public class ServiceRegistrator {
    public long registerService(Object service) {
        final long id = IdGenerator.generateNewId();
        // Other logic...
        return id;
    }
}

To mock the static method `generateNewId()`, you would use PowerMock's `mockStatic` method along with EasyMock. Here's how you can write a test for it:

java
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(IdGenerator.class)
public class ServiceRegistratorTest {

    @Test
    public void testRegisterService() throws Exception {
        long expectedId = 42;
        
        // Mock the static method
        PowerMock.mockStatic(IdGenerator.class);
        PowerMock.expect(IdGenerator.generateNewId()).andReturn(expectedId);
        PowerMock.replay(IdGenerator.class);
        
        // Create an instance of the class under test
        ServiceRegistrator tested = new ServiceRegistrator();
        
        // Call the method that uses the static method
        long actualId = tested.registerService(new Object());
        
        // Verify the static method was called
        PowerMock.verify(IdGenerator.class);
        
        // Assert the result
        assertEquals(expectedId, actualId);
        
        // Clean up
        PowerMock.resetAll();
    }
}

Using PowerMock with Mockito

Now, let's see how to achieve the same using Mockito with PowerMock. This approach is similar but uses Mockito's syntax for stubbing expectations.

Assume we have a class `StaticUtil` with a static method `firstStaticMethod()` that we want to mock.

java
public class StaticUtil {
    public static String firstStaticMethod(String param) {
        return "Original Result";
    }
}

Here's how you can mock this method using PowerMock with Mockito:

java
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(StaticUtil.class)
public class StaticUtilTest {

    @Test
    public void testMethodThatCallsStaticMethod() {
        // Mock all static methods in the class
        PowerMockito.mockStatic(StaticUtil.class);
        
        // Set up the expectation for the static method
        String param = "testParam";
        String expectedValue = "Mocked Result";
        Mockito.when(StaticUtil.firstStaticMethod(param)).thenReturn(expectedValue);
        
        // Call the method that uses the static method
        String actualValue = StaticUtil.firstStaticMethod(param);
        
        // Verify the static method was called
        PowerMockito.verifyStatic(StaticUtil.class);
        StaticUtil.firstStaticMethod(param);
        
        // Assert the result
        assertEquals(expectedValue, actualValue);
    }
}

Key Points

- Annotations: Use `@RunWith(PowerMockRunner.class)` to enable PowerMock and `@PrepareForTest` to specify the class containing the static method you want to mock.
- Mocking Static Methods: Use `PowerMock.mockStatic()` with EasyMock or `PowerMockito.mockStatic()` with Mockito to enable mocking of static methods.
- Setting Expectations: Use `PowerMock.expect()` with EasyMock or `Mockito.when()` with Mockito to set up return values for the static methods.
- Verification: Use `PowerMock.verify()` with EasyMock or `PowerMockito.verifyStatic()` with Mockito to verify that the static methods were called as expected.

Conclusion

PowerMock provides powerful capabilities to mock static methods, which can be challenging with standard Mockito. By combining PowerMock with either EasyMock or Mockito, you can effectively test code that uses static methods. However, it's worth noting that Mockito itself now supports mocking static methods using the `mockStatic` method from the `mockito-inline` library, but this requires a different setup and is not covered in this example.

Citations:
[1] https://github.com/powermock/powermock/wiki/mockstatic
[2] https://github.com/powermock/powermock/wiki/mockito
[3] https://github.com/powermock/powermock/wiki/Mockito/cebcc5324cd3991cacdf5e1319209e5c4cd80fd3
[4] https://stackoverflow.com/questions/64607243/mocking-a-static-method-using-powermockito
[5] https://stackoverflow.com/questions/10583202/powermockito-mock-single-static-method-and-return-object
[6] https://www.baeldung.com/mockito-mock-static-methods
[7] https://blog.knoldus.com/mocking-static-methods-with-powermock/
[8] https://www.reddit.com/r/javahelp/comments/1g9f3a2/not_able_to_mock_a_static_method_in_beam_pipeline/
[9] https://www.testim.io/blog/mocking-static-methods-mockito/