PowerMock + TestNG = True

After having it on our todo list for at least a year we’ve finally managed to integrate PowerMock with TestNG 5.11 as of PowerMock version 1.3.5. This is a big milestone of the project since we’ve now demonstrated that PowerMock is decoupled from both a specific test framework and a specific mock framework. The TestNG integration still needs improvements and we’re happy for all suggestions, comments or patches.

So how do you configure PowerMock to use TestNG? First of all follow the instructions on the getting started page which states everything you need to know to get started with or without Maven. The trick is then to specify the PowerMock object factory in the TestNG suite.xml. An example can be seen here:

Without specifying this object factory the test will never be bootstrapped properly by PowerMock and thus will fail if any PowerMock functionality is used in the test.

Example

Now that we know how to bootstrap PowerMock and TestNG what does a test look like? If you’re used to PowerMock there will be no surprises. As usually you have to prepare the class that is normally not testable/mockable for test using the @PrepareForTest annotation. Consider that we have a class like this:

When testing this class we might want to mock the static call to the IdGenerator. The full test will look like this using the Mockito extension API:

Using the EasyMock API extension the test could look like this:

Advanced

Under the hood the PowerMock object factory also creates a proxy around the test class. This proxy adds support for creating and injecting mocks using the @Mock annotation and clears state created by PowerMock between each test. This means that you can create and inject mocks to your test like this:

This works for both the EasyMock and Mockito API extensions. If you for some reason doesn’t like that your test class is proxied you can manually extend the org.powermock.modules.testng.PowerMockTestCase to get the same functionality.

Round up

There’s still much work to be done with the TestNG object factory such as getting better support for scoped injections and getting PowerMock test listeners in place. If you’d like to contribute in any way just drop us a note using the mailing list. Last but not least we would like to thank Dan Fabulich of the TestNG team for all the help making this possible.

This Post Has 12 Comments

  1. Hi Johan!!

    I am using TestNG 5.11+Mockito 1.8+PowerMockito 1.3.5

    Facing lot of trouble with third party xml, log4j and spring frameworks.
    I tried all possible tricks (solutions) available on web. After opting tricks now i am getting ClassCastException while executing new SAXParserFactory.newInstance() code. This code is in some third party jar xmlrpc-Common.jar 3.1. I Dont have the source code of it and dont want to manipulate this jar anyways.

    Looks like two diffrent classloader problem. I mean Abstract class is loaded by MockClassLoader and implementing class instance is in diffrent classLoader

    I tried to use @PowerMockIgnore annotation. But that too having bug in PowerMockito1.3.5 versrion(Other versions i didnt try). I get NullPointerException in string class if i use this.

    While Debugging this NullPointerException i found two bugs in the PowerMockito1.3.5 Code. Here goes the code snippet having bug

    Class::org.powermock.core.classloader.DeferSupportingClassLoader

    public void addIgnorePackage(String… packagesToIgnore) {
    if (packagesToIgnore != null && packagesToIgnore.length > 0) {
    final int previousLength = deferPackages.length;
    deferPackages = new String[previousLength + packagesToIgnore.length];
    System.arraycopy(packagesToIgnore, 0, deferPackages, previousLength, packagesToIgnore.length);
    }

    in this method developer is creating a new array list and assigning deferpackeges referece to it.Becoz of the earlier string array get wiped out to which thie reference was reffering. And finally deferpackages reference refer to an array having values null in starting and after some null values it stores the values supplied in PowerMock Ignore annotation.

    Also found one bug in mockclassLoder

    return (shouldModifyAll() || WildcardMatcher.matchesAny(modify, s)) && !shouldIgnore(deferPackages, s);

    this line will always return the false value becoz of shouldModifyAll() call

    Can u plz explain the intended behaviours of these code snnipets.

    And also Plz Tell me the solution of my earlier ClassCastException problem.
    If you quickly reply this, it wud b gud. As rit now i m evaluating PowerMockito to be used or not to e used in our project

    Thanks in advance……

  2. Could you please join and use our mailing list and post this message there instead? powermock at googlegroups dot com.

  3. Hi Johan!!

    As u mentiones i have posted the above message in googlegroup discussions session with the topic headline “ClassCastException in SaxParserFactory.newInstance() call”

    It will be great if u quickly help me to resolve these kind of problems with powermock and xml frameworks.

    thanks

  4. Hi,

    Can you write a test case to mock a static fn. using powermock + easymock +testng.
    I am unable to do that and can’t find anything on internet for this combo.
    Help plz

  5. Is it possible to use powermock/mockito/testng with dataproviders. For some reason we keep getting a class mismatch exception when using tests with dataproviders.

  6. import org.powermock.api.mockito.PowerMockito;
    import org.powermock.core.classloader.annotations.PrepareForTest;
    import org.powermock.modules.testng.PowerMockTestCase;
    import org.testng.annotations.Test;

    import com.cisco.mos.sm.utils.SMUtils;

    @PrepareForTest(SMUtils.class)
    public class DeleteMe extends PowerMockTestCase {

    @Test
    public void demoStaticMethodMockingUsingTestNGAndMockito() {
    PowerMockito.mockStatic(SMUtils.class);

    PowerMockito.when(SMUtils.test()).thenReturn(“HI”);

    PowerMockito.verifyStatic();
    SMUtils.test();

    }

    Using java 1.7 get a crash.
    https://code.google.com/p/powermock/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Priority%20Milestone%20Owner%20Summary&groupby=&sort=&id=414

  7. Hi Johan,
    I am not able to configure my Spring project with TestNG using PowerMock.
    Java Version I am using is 1.7

    I tried to search working example on Spring integrated with TestNG using PowerMock. If possible can you please mail me a working example for the same.

    Thanks,
    Umesh

  8. Thanks for your post, It supports me a lot
    I have a question. How can I integrate with Spring framework? my unittest must initialize the ApplicationContext, and It stops at @PrepareForTest. I already researched but I have no idea with this. Can you help me to give an example?
    Thanks.

Leave a Reply

Close Menu