Arthur Zagretdinov edited this page Jun 15, 2017 · 1 revision

Using PowerMock with TestNG

Since version 1.3.5 PowerMock has basic support for TestNG. Supported versions are:

TestNG PowerMock
6.9.10+ 1.6.5+
5.13.1+ 1.4.5+
5.12.1 1.3.8 - 1.4
5.11 1.3.6 & 1.3.7

Using PowerMock 1.4.9 and 1.4.10 without Maven

There was a bug in the release process which excluded the PowerMockTestCase from the full release build. Please download the missing dependency here (sources, javadoc).

How to write tests

Just as with the JUnit runners you need to prepare the classes that are normally not mockable by using the @PrepareForTest annotation. A full example using the Mockito API extension:

Class under test:

public void methodToTest() {
   ..
   final long id = IdGenerator.generateNewId();
   ..
}

The test with TestNG:

@PrepareForTest(IdGenerator.class)
public class MyTestClass {
    @Test
    public void demoStaticMethodMocking() throws Exception {
	mockStatic(IdGenerator.class);
     
	when(IdGenerator.generateNewId()).thenReturn(2L);		
 
	new ClassUnderTest().methodToTest();
 
	// Optionally verify that the static method was actually called
	verifyStatic();
	IdGenerator.generateNewId();
    }
}

For this to work you need to tell TestNG to use the PowerMock object factory as seen below:

Configure TestNG to use the PowerMock object factory

Using suite.xml

In your suite.xml add the following in the suite tag:

object-factory="org.powermock.modules.testng.PowerMockObjectFactory"

e.g.

<suite name="dgf" verbose="10" object-factory="org.powermock.modules.testng.PowerMockObjectFactory">
    <test name="dgf">
        <classes>
            <class name="com.mycompany.Test1"/>
            <class name="com.mycompany.Test2"/>
        </classes>
    </test>
</suite>

If you're using Maven you may need to point out the file to Surefire:

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-surefire-plugin</artifactId>
	<configuration>
	    <suiteXmlFiles>
		<suiteXmlFile>suite.xml</suiteXmlFile>
	    </suiteXmlFiles>
	</configuration>
</plugin>

Programmatically

Add a method like this to your test class:

@ObjectFactory
public IObjectFactory getObjectFactory() {
    return new org.powermock.modules.testng.PowerMockObjectFactory();
}

or to be on the safe side you can also extend from the PowerMockTestCase:

@PrepareForTest(IdGenerator.class)
public class MyTestClass extends PowerMockTestCase {
   ...
}

Here's an example submitted by Adrian Moerchen:

package me.scrobble.example.powermock.testng;

import static org.mockito.Mockito.when;

import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockObjectFactory;
import org.testng.Assert;
import org.testng.IObjectFactory;
import org.testng.annotations.ObjectFactory;
import org.testng.annotations.Test;


@PrepareForTest(StaticFactory.class)
public class ObjectFactoryExample {

	/**
	 * We need a special {@link IObjectFactory}.
	 * 
	 * @return {@link PowerMockObjectFactory}.
	 */
	@ObjectFactory
	public IObjectFactory getObjectFactory() {
		return new org.powermock.modules.testng.PowerMockObjectFactory();
	}

	/**
	 * Test if it is possible to create a cipher using
	 * 
	 * @throws Exception
	 *             Thrown if something went wrong.
	 */
	@Test
	public void test() throws Exception {
		Assert.assertEquals("AES", StaticFactory.getMethod());
		PowerMockito.mockStatic(StaticFactory.class);
		when(StaticFactory.getMethod()).thenReturn("DES");
		Assert.assertEquals("DES", StaticFactory.getMethod());
	}
}

Mock initialization

Be aware that you can only create mocks in non-static "before" and "test" methods when you use PowerMock and TestNG. You cannot create mocks during field initialization. For example the following is not guaranteed to work:

public class SomeTest extends PowerMockTestCase{
    
    MyClass myClassMock = mock(MyClass.class); // This is not guaranteed to work!
    ...
}

It's also currently not possible to create mocks inside static before methods, e.g.

@BeforeMethod
public static void beforeMethod() throws Exception {

        MyClass myClassMock = mock(MyClass.class); // This is not guaranteed to work!
       
 }
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.