PowerMock Part 2

In JayView 17 we presented a short introduction to PowerMock, a framework that allows you to create automated tests for almost any code in isolation from its environment. In this article we’ll dig a bit deeper into PowerMock and explore the goals and more of its feature set.

Background

PowerMock is intended for developers who want to unit test code in isolation from its environment. The environment may be for example other classes or
objects, other systems such as a database or a file-system. To isolate the unit you
can use a technique called mocking. Mocks let you record and verify behavior
according to your needs in order to get a deterministic behavior when executing
your test, for example provide a certain return value. A similar technique is stubs
that simply remove functionality and you don’t care about the return value.

Why?

There already exists frameworks that provide both mocks and stubs, so why
create another one? First of all PowerMock is not a new framework built from
scratch, instead it extends existing mock frameworks such as EasyMock and
Mockito. In most cases these frameworks are still sufficient. However, there are
cases when more power is needed!

To be able to use mock objects your code needs to be designed in a way that
makes it possible to replace collaborators, for example by using the Dependency
Injection pattern. Most often this is a good thing, but sometimes it leads to more
complexity and a more complicated production code that is more difficult to
understand. Another problem is legacy code which is seldom designed with unit
testing in mind. When trying to introduce Dependency Injection you are often
forced to perform a gigantic refactoring touching almost every class. Depending
on how brave you are this can either be a problem or an opportunity.

Another common situation is when there is some initialization routine in your
code or some third party library that does something that prevents you from
unit testing your code. This can both be a constructor or a static initializer. For
example, did you know that an interface can have a static initializer? This means
that just implementing an interface can execute code beyond your control!

Goals

Since there are many good mock frameworks out there already we think that
instead of creating something entirely new we want to reuse the API’s that
people already use and extend them with more capabilities. This means that
PowerMock consists of extension APIs to other popular mock frameworks.
EasyMock was the first API that we supported since we have been using it a lot.
In version 1.1 we also have some basic support for Mockito and we have serious
plans for a JMock extension. PowerMock is fully extendable and you can create
an extension on your own as well.

A key goal of PowerMock is to allow you to unit test your code without having to
think about the testability aspects. We would of course never encourage you to
write inflexible code that is hard to maintain, but we leave the design decisions
up to you and not to the technical limitations of a test or mock framework.

Another important goal is that PowerMock should be just another jar file. As a
user you should not have to care how PowerMock does its magic. You just put it
in your classpath and then you’re good to go. You don’t need to install any IDE
plugin, change the JVM settings or mess with your build environment.

When to use it

Using a 3rd party or legacy framework

  • Sometimes communication with a particular framework is done through
    static methods (for example Java ME). PowerMock allows you to setup
    expectations for these static methods and simulate the behavior you need
    to test.

  • Other frameworks require you to subclass classes that contain static
    initializers or constructors doing something that prevents you from unit-
    testing your code in isolation. PowerMock allows you to remove static
    initializers and suppress constructors. It also allows you to mock classes
    inside a signed jar files even though a class is package-private.

Design

  • You really want to enforce the fact that some methods are private. PowerMock allows mocking and testing of both private and final methods..
  • You want to read or write private state from your test without adding unnecessary methods to the production code that are used only for test purposes.
  • In some cases you want to create a new instance of an object in your production code but still be able to replace this instance with a mock object from your test.

Examples

All examples in this article are written with the EasyMock extension API.
The examples are written in a way that easily demonstrates the capabilities of
PowerMock and are sometimes very naive. In the examples both the code being
tested and the actual test are completely pointless and is not a recommended
way of coding! The reason why we use such examples is of course that code that
typically need PowerMock is often quite complex and it would be hard to focus
on what we are trying to demonstrate.

When writing tests with PowerMock you basically always need to supply
two annotations at the class-level of your test as you will see in the examples
below. The first is the RunWith annotation which tells JUnit to run the test
with a specific JUnit runner. In PowerMock’s case you always specify the
PowerMockRunner, i.e. @RunWith(PowerMockRunner.class). This is what
bootstraps the entire PowerMock framework and this is how you can see that
a test is using PowerMock. The PowerMockRunner initializes PowerMock’s
classloader which starts to load all classes relevant for your particular test. Some
of these classes need to be prepared in order to allow for testability. These are
the classes that you wish to mock, for example those containing final or static
methods. You supply these classes to the @PrepareForTest annotation. What
PowerMock does then is to modify the byte-code of these classes at run-time so
that they become testable. Let’s look at a couple of examples to clear things up.

Mocking final classes or methods

Imagine writing a unit test for this fictive class:

For those of you who are used to unit testing it doesn’t look like any problems
at first since it’s easy to inject a mock implementation of the SomeDao class to
an instance of the SomeService at construction since it’s using the Dependency
Injection pattern. But let’s look at the actual implementation of the SomeDao
class.

As you may see this class communicates with a database which is typically
something we want to avoid in a unit test. The problem is that both the class
and the method is final so we wouldn’t be able to mock this class with standard
EasyMock. But PowerMock makes this possible using the standard EasyMock
syntax:

Looking closely you may see that we’re using the replayAll() and verifyAll()
methods of the PowerMock API. These methods will replay and verify all mocks
created by PowerMock so that you don’t have to keep track of them yourself.
Of course PowerMock provides the standard replay(..) and verify(..) methods as
well if you’d rather want to use those.

Mocking and testing private methods

Sometimes you may want to enforce encapsulation and use private methods.
There’s a debate going on on whether one should test private methods by
themselves or not but we’ll leave that decision up to you. Mocking a method
of the class being tested is known as partial mocking. PowerMock lets you do
partial mocking and also invoke private methods during a test. Let’s say we have
the following class:

DataService has two public methods that both calls the private modifyData
method and you may want to unit test these methods. You may want to test
replace replaceData without invoking modifyData or maybe just test the private
method itself. PowerMock lets you do both. To mock the modifyData method
you create a partial mock using PowerMock.createPartialMock(..) and to setup
expectations for a private method you use the PowerMock.expectPrivate(..)
method. For the replaceData method the test could look like this:

PowerMock also provides utility methods located in the Whitebox class that can
assist you with accessing internal state, executing private methods or constructors
etc. So if we’d like to test the modifyData method instead of mocking it we can
do so by using the Whitebox.invokeMethod(..) functionality:

As you can see you just supply the instance containing the method, the method
name itself and the arguments that you want to pass to the method.

Note that in general you should avoid testing and mocking private methods
as these tests are often fragile and tightly coupled with the implementation.
During refactoring, when you most need your test cases, you may be forced to
simply throw away tests that are too tightly coupled to the old implementation.
Therefore, when writing tests you should always focus on testing expected
behavior and not check implementation details.

Mocking new object constructions

Let’s say we have a class that looks like this:

When unit testing this class we want to isolate ourselves from the file-system
environment since what’s interesting for us to test whether a directory already
exists or not. So what we want to do is to create a mock object of the File class
and replace the file instance with this mock object. This is something that is
normally not possible since we’re creating a new File instance in our code. But
with PowerMock you can indeed do so:

As you can see we’re using the expectNew functionality of PowerMock to
intercept the call to new File and return the mock object instead. Note that we
prepare the Directory class for test and not the File class. The reason for this is
that it is the Directory instance that creates a new File instance and thus the File
class itself doesn’t have to be prepared for test.

Suppressing unwanted behavior

Sometimes you want to suppress a method, constructor or static initializer
of your production code when executing your test because they are of no
importance to the test or they even prevent you from testing your unit. Let’s
take a look at the following example:

This seems like an easy class to unit test (so easy in fact that you probably
shouldn’t test it, but let’s do it anyway for demonstration purposes). But wait,
let’s look at what the ThirdPartyFrameworkBaseClass class looks like:

This class tries to load a dll file which may not be present when you run
a unit test for the ExampleWithBaseClass class and thus will lead to
an exception. With PowerMock you can just suppress the constructor
of the ThirdPartyFrameworkBaseClass so that you can unit test the
ExampleWithBaseClass class in isolation from the native framework dll.
Sometimes this may also save you a lot of time not having to bootstrap an entire
framework. You can achieve this by using the suppressConstructor method of
the PowerMock API. In this case we would do:

That’s it! PowerMock can also suppress static initializers, methods and fields.

Access private state

For mutable objects internal state may change after a method has been invoked.
When unit testing such objects it’s good to have an easy way to get a hold of this
state and see if it has updated accordingly. PowerMock supplies several useful
reflection utilities specially designed for unit testing. All of these reflection
utilities are located in the org.powermock.reflect.Whitebox class.

For demonstration purposes let’s say we have a class that looks like this:

What we’re interested in testing here is that if we add a service we want to make
sure that it’s added to the services set. But since the services field is private this
is normally not so easy. But with PowerMock you can do like this:

As you can see we’re using the Whitebox.getInternalState(..) functionality to
get the services field from the ServiceHolder instance. Note that we specified
the type of the field (Set.class) instead of specifying the name of the field. This
makes the code more refactor friendly as the name of the field can change.
You could have achieved the same result by using the not-so-refactor-friendly
alternative Whitebox.getInternalState(tested, “services”). Sometimes you need
to revert to this second approach anyway, for example if you have two fields of
the same type in the class.

Once again, accessing private state will couple the test to the implementation
and should in general be avoided. However, we have seen several cases where
this has been necessary in order to test the code without compromising
encapsulation in the production code.

Summary

As you’ve seen PowerMock is capable of mocking and testing many things that
are normally difficult or even impossible. PowerMock gives you more design
options and does not force you to do trade-offs in favour for testability. However,
always design your tests carefully and avoid tight coupling between the test
cases and implementation details. PowerMock have many more features than we
have shown here and we also have a lot in store for the future. Please have a look
at http://www.powermock.org for more information, downloads and tutorials.

Johan Haleby
Jan Kronquist

Originally published in JayView.

This Post Has 3 Comments

  1. Such a nice tutorial my friend.

  2. Alltest.java:
    @RunWith( Suite.class )
    @SuiteClasses( {test1.class, test2.class} )
    public class AllTests
    {

    @BeforeClass
    public static void initTest() throws Exception
    {

    }

    @AfterClass
    public static void disposeTest()
    {

    }
    }

    test1.java
    @RunWith( PowerMockRunner.class )
    @PrepareOnlyThisForTest( {Object.class} )
    public class test1 extends TestCase
    {
    @Before
    public void setUp() throws Exception
    {

    }

    @Test
    public void testcase()
    {
    Shell sh = new Shell();
    assertTrue( true );
    }

    }

    test2.java

    @RunWith( PowerMockRunner.class )
    @PrepareOnlyThisForTest( {Object.class} )
    public class test2 extends TestCase
    {
    @Before
    public void setUp() throws Exception
    {

    }

    @Test
    public void testcase()
    {

    Shell sh = new Shell();
    assertTrue( true );
    }
    }

    when run alltest i get error:
    java.lang.UnsatisfiedLinkError: Could not load SWT library. Reasons:
    no swt-win32-3650 in java.library.path
    no swt-win32 in java.library.path
    Native Library C:Usersw00207976AppDataLocalTempswtlib-32swt-win32-3650.dll already loaded in another classloader
    Can’t load library: C:UsersW00207~1AppDataLocalTempswtlib-32swt-win32.dll

    comment:
    i need use swt api

Leave a Reply

Close Menu