Mocking static methods with PowerMock
Unit testing is great. As we learn it it's excellent. As we work on greenfield projects it's beautiful and sweet. The real problems start on the real projects.
Sometimes you must test classes that depend on other classes. A common solution is mocking. If you own all the implementation it is easy, as you can create an interface and mock implementation for it and use it in your tests. There are frameworks that help you with mocking and make it easier (for example Mockito). Mockito however does not support mocking for static methods.
Today I came across PowerMock. PowerMock is a framework that extends other mock libraries, as EasyMock and Mockito. This let's you use your favourite framework with some new power capabilities.
Let's create a sample test mocking a static method.
For this purpose I've created following class:
package sample; public class StaticHelper { public static String getName() { return "MyName"; } }
And another helper class that uses the static one:
package sample; public class NonStaticHelper { public String getName() { return StaticHelper.getName(); } }
And here is the test:
package sample; import static org.junit.Assert.assertEquals; 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(StaticHelper.class) public class TestHelper { @Test public void testHelperMethod() { PowerMockito.mockStatic(StaticHelper.class); Mockito.when(StaticHelper.getName()).thenReturn("MockedName"); assertEquals("MockedName", StaticHelper.getName()); NonStaticHelper helper = new NonStaticHelper(); assertEquals("MockedName", helper.getName()); } }
We need to define a runner and declare which classes should be prepared for testing. PowerMock uses a custom class loader and bytecode manipulation and these annotation are required to let it know which classes to handle.
In the test itself we use the mockStatic() method to say that getName() method will be mocked.
Further code is a standard Mockito syntax for mocking method call and return values.
Also we can notice that once static method is mocked everytime we call it it returns the mocked value. So when we test the NonStaticHelper method is already uses the mocked version.
Maybe it's not an extensive example but it's just the first time I used PowerMock
On the project website you can download a zip file with JUnit, Mockito and PowerMock in one bundle which let's you start easily.
Here is an eclipse project with all the libraries needed: PowerMockUsage
java |
Thank you so incredibly much for posting this! It couldn’t have come at a better time, and has helped me to test some *really* difficult to test stuff.
Thanks and keep on posting!
Jim