Using PowerMock + TestNG to Mock a Static Class
￼ This week I needed to test a class that depended on a method from an static class. I saw we were using PowerMock and thought to myself: “Well this sounds pretty common, I bet it’s easy to accomplish”. But of course I ran into half a dozen issues before I was able to make it work. Here’s my two cents to make your experience easier than mine.
Let’s start with the ingredients. To mock static methods you’ll need a couple of libraries:
When choosing your library version you’ll need to make sure PowerMock and TestNG versions are compatible. You can do so by comparing your versions with the ones specified here.
Also, if you’re not using Maven to include PowerMock in your project make sure you also add it’s dependencies. You’ll find a zip file containing everything you need here.
Writing the test
To have the test working you’ll need to do 3 things:
- Configure TestNG to use the PowerMock object factory
@PrepareForTestannotation to prepare the static class
- Mock the static class method
- Write the rest of the test
Let’s go one by one:
1. Configure TestNG to use the PowerMock object factory
There are a bunch of ways of doing this, namely:
- Configure it on the
- Extending your test class with
- Or by adding a method like this to your test
1 2 3 4
I choose to go with the latter because I don’t use the
suite.xml file and adding an annotated method is less restrictive than extending a class. But feel free to use whatever works for you.
You’ll need to prepare your static class for mocking. You can do so with the
@PrepareForTest annotation like this:
1 2 3 4
Note that you can pass an array of classes to the annotation if you need to prepare multiple classes.
Now you’re ready to mock the static method like this:
1 2 3 4 5 6 7 8
4. Writing the rest
Ok let’s put everything together and write the rest of the test
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Of course this is an oversimplified example. The cool thing about mocking static methods is that the static call you may need to mock may be hidden under several layers of abstraction. Using this approach you are able to mock the static call and test your classes without changing a single line of production code.
Some things to watch out for
There are a few things to keep in mind when initializing the mock:
- You cannot create mocks during field initialization.
- You cannot create mocks inside before static methods.
Finally I also run into the following error when running my test:
Turns out that, as explained here Java 7 introduced a stricter verification and changed the class format. The byte code generation library PowerMock uses is generating code that does not comply with the new verification. But worry not, this validation can be disabled by passing
-noverify as argument to the JVM.
If you’re running you’re using Maven to run your tests remember to add the argument to your plugin configuration.
This guide uses EasyMock but you can also use Mockito↩