Monday, April 29, 2013

Unit testing with PowerMock

In this article I will implement several unit tests using PowerMock framework. This framework is more powerful than other libraries and allows you to mock static methods, private methods and change field properties among other things. I will use the Mockito extension but it also supports EasyMock.

1   Installation

If you use Maven, you can add the following dependencies to your pom.xml:
Otherwise, you can get the libraries here.

2   Preparing the tests

You must add the @RunWith annotation. This annotation will tell JUnit to use the class PowerMockRunner to run the tests.
I'm going to test Foo.class. Using the spy method, all real methods of the class will be invoked except those I mock.

3   Mocking private methods

I want to test methodWithPrivateDependency, but this method internally calls a private method which, let's say, calls an external resource.
The test:
The @PrepareForTest annotation tells PowerMock to prepare the class so it can manipulate it. This is necessary if the class is final, or it contains final, private, static or native methods that should be mocked. In this case, I will need to mock the private method.

If you put this annotation at class level, it will affect all test methods within the class. It would be as follows:

4   Mocking static access

The next method that needs to be tested gets some information by accessing a static method of an inner static class. You need to mock the static access.

The method to test:
The static class:
The test:
I use the @PrepareForTest annotation because I need to mock the static method getData of this class.

5   Mocking chained dependencies

In this example, I want to mock the chainMocks method. There's a singleton Helper class which returns a manager from which the method to test invokes it.
The test:
I only need to prepare Helper class for test because I need to mock its static method getInstance (that's not the case for ConfigurationManager where initializeRegistry is a public instance method).

No comments:

Post a Comment