Using PowerMock to mock/stub static void method calls in JUnit.

Sometimes  you do come across snippets of code that prove to be tricky while writing their JUnit tests.  One such scenario is the case of static void call, though some people would argue to extract the static void call into a separate method but that is old-school. PowerMock junit runner lets you  even mock static void and normal static calls. Let us take a look at both approaches the old one and the new one which uses PowerMock.

Older Approach


public class MyAction {

public String performSearch() {

// some logic operations

// the detestable static call
staticCall();

return "Success";
}

protected void staticCall() {
// <strong>the static void method call</strong>
MyStatic.staticMethod();
}

}

class MyStatic {

public static void staticMethod() {
throw new NullPointerException("Bazinga!");

}

}

In the above code snippet we can see that the static void call is extracted out in a separated method, now while writing the JUnit test for MyAction java class we can have anonymous sub-class which overrides the staticCall() method with it’s own implementation to avoid calling this method. Below code snippet elucidates the overriding

public class MyActionTest {

MyAction action;

@Before
public void setUp() {
action = new MyAction(){
protected void staticCall() {

System.out.println("inside overridden method");
};
};
}

In the above snippet we can see that I have overridden the staticCall() method, now while executing the Junit test the super-class method containing the static call is never invoked and hence our purpose is solved of avoiding the static call. But the reason I don’t consider this approach clean is that our code should not be changed in order to  make our Junit tests easier to write. Junit test should test existing running code without the need of modifying the code to meet JUnit’s need.

Now lets use PowerMock to mock the static void calls.


@RunWith(PowerMockRunner.class)
@PrepareForTest(MyStatic.class)
public class MyActionTest {
MyAction action;

@Before
public void setUp() {
action = new MyAction();
}

@Test
public void testPerformSearch() {

PowerMockito.spy(MyStatic.class);
PowerMockito.doNothing().when(MyStatic.class);
MyStatic.staticMethod();
Assert.assertEquals("Success", action.performSearch());
}
}

In the above code we have used PowerMock’s spy feature to partially mock the object, once you partial mock the object you have to stub the behavior i.e. prepare some canned calls. Here the PowerMock’s ability lies in the below three statements

PowerMockito.spy(MyStatic.class);
PowerMockito.doNothing().when(MyStatic.class);
MyStatic.staticMethod();

First we partially mock the MyStatic Class, then in the second line the doNothing() method is used to specify that the A static method call by the class MyStatic should result in doing nothing. Now since the object is partially mocked thus we also need to specify the method whose invocation is canned by doNothing() method, we do this in the 3rd statement MyStatic.staticMethod() , thus now it’s more of record-playback pattern wherein we have initially recorded the doNothing() behavior and then played the MyStatic.staticMethod().

Conclusion   The PowerMock approach is best possible solution i could find for mocking static calls without changing actual code, if you have any other tricks up your sleeve do share them!

You can download the powermock mocktio jars zip from here

About these ads

About Tarun Sapra
Agile Java developer @ Xebia India

3 Responses to Using PowerMock to mock/stub static void method calls in JUnit.

  1. Johan says:

    This would probably work in PowerMock as well:

    suppress(method(MyStatic.class, “staticMethod”));

    but it’s not type-safe since you need to write the method name in text. You could suppress all static methods though:

    suppress(allMethodsIn(MyStatic.class));

  2. Tarun Sapra says:

    Hey Johan,

    I tried the following 1 line snippet pf code
    PowerMockito.suppress(MyStatic.class.getMethod(“staticMethod”, (Class[])null));

    and it worked (casting is to prevent the warning)

    Can you elaborate what do you mean by “suppress(allMethodsIn(MyStatic.class));”

  3. Pingback: JavaPins

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: