PowerMock module for TestNG that enables mocking of static methods, constructors, final classes and methods, private methods, and removal of static initializers in TestNG-based unit tests.
npx @tessl/cli install tessl/maven-org-powermock--powermock-module-testng@2.0.0PowerMock module for TestNG that enables mocking of static methods, constructors, final classes and methods, private methods, and removal of static initializers in TestNG-based unit tests. This module provides seamless integration between PowerMock's advanced mocking capabilities and the TestNG testing framework.
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-testng</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>Or Gradle:
testImplementation 'org.powermock:powermock-module-testng:2.0.9'import org.powermock.modules.testng.PowerMockObjectFactory;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;For base class support (requires powermock-module-testng-common dependency):
import org.powermock.modules.testng.PowerMockTestCase;Option 1: Configure PowerMockObjectFactory in TestNG Suite XML
<suite name="MyTestSuite" object-factory="org.powermock.modules.testng.PowerMockObjectFactory">
<test name="PowerMockTests">
<classes>
<class name="com.example.MyTest"/>
</classes>
</test>
</suite>Option 2: Extend PowerMockTestCase (requires powermock-module-testng-common)
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.annotations.Test;
import static org.powermock.api.mockito.PowerMockito.*;
@PrepareForTest(StaticClass.class)
public class MyTest extends PowerMockTestCase {
@Test
public void testStaticMocking() throws Exception {
// Mock static method
mockStatic(StaticClass.class);
when(StaticClass.staticMethod()).thenReturn("mocked");
// Test code here
assertEquals("mocked", StaticClass.staticMethod());
// Verify static method was called
verifyStatic(StaticClass.class);
StaticClass.staticMethod();
}
}Option 3: Manual ObjectFactory Setup
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockObjectFactory;
import org.testng.IObjectFactory;
import org.testng.annotations.ObjectFactory;
import org.testng.annotations.Test;
import static org.powermock.api.mockito.PowerMockito.*;
@PrepareForTest(StaticClass.class)
public class MyTest {
@ObjectFactory
public IObjectFactory getObjectFactory() {
return new PowerMockObjectFactory();
}
@Test
public void testWithPowerMock() {
// PowerMock functionality available
mockStatic(StaticClass.class);
when(StaticClass.staticMethod()).thenReturn("mocked");
// Test code here
assertEquals("mocked", StaticClass.staticMethod());
// Verify
verifyStatic(StaticClass.class);
StaticClass.staticMethod();
}
}The PowerMock TestNG module works by intercepting TestNG's test instance creation process:
The module integrates with TestNG's object factory mechanism to enable PowerMock's bytecode manipulation capabilities while maintaining compatibility with standard TestNG tests.
Primary integration mechanism that automatically enables PowerMock for tests with PowerMock annotations.
public class PowerMockObjectFactory implements IObjectFactory {
public PowerMockObjectFactory();
@Override
public Object newInstance(Constructor constructor, Object... params);
}The PowerMockObjectFactory automatically detects when test classes or methods are annotated with @PrepareForTest or @SuppressStaticInitializationFor and enables PowerMock classloader accordingly. For non-PowerMock tests, it uses the standard TestNG object factory.
Usage example:
<suite name="TestSuite" object-factory="org.powermock.modules.testng.PowerMockObjectFactory">Optional base class providing automatic mock lifecycle management and PowerMock integration.
public class PowerMockTestCase {
public PowerMockTestCase();
@BeforeClass
protected void beforePowerMockTestClass() throws Exception;
@AfterClass
protected void afterPowerMockTestClass() throws Exception;
@BeforeMethod
protected void beforePowerMockTestMethod() throws Exception;
@AfterMethod
protected void afterPowerMockTestMethod() throws Exception;
@ObjectFactory
public IObjectFactory create(ITestContext context);
}Lifecycle Methods:
beforePowerMockTestClass(): Clears mock repository and configures classloader contextafterPowerMockTestClass(): Restores original classloader contextbeforePowerMockTestMethod(): Injects mock fields before each test methodafterPowerMockTestMethod(): Clears mock fields and repository after each test methodcreate(ITestContext): Returns PowerMockObjectFactory instance for TestNGUsage example:
@PrepareForTest(MyStaticClass.class)
public class MyTest extends PowerMockTestCase {
@Test
public void testWithPowerMock() {
// PowerMock functionality automatically available
mockStatic(MyStaticClass.class);
// ... test code
}
}The module includes internal implementation classes that handle the heavy lifting:
// Internal class referenced by PowerMockObjectFactory
public class PowerMockClassloaderObjectFactory implements IObjectFactory {
public PowerMockClassloaderObjectFactory();
@Override
public Object newInstance(Constructor constructor, Object... params);
}Note: Internal classes are implementation details and should not be used directly. Use PowerMockObjectFactory or PowerMockTestCase for public API access.
Configure PowerMock at the suite level to enable for all tests:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="PowerMockSuite" object-factory="org.powermock.modules.testng.PowerMockObjectFactory">
<test name="MyTests">
<classes>
<class name="com.example.StaticMockTest"/>
<class name="com.example.FinalClassTest"/>
</classes>
</test>
</suite>PowerMock is automatically enabled when these annotations are present:
@PrepareForTest(ClassName.class) - On class or method level@SuppressStaticInitializationFor("package.ClassName") - On class or method levelPattern 1: Method-level PowerMock
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockObjectFactory;
import org.testng.IObjectFactory;
import org.testng.annotations.ObjectFactory;
import org.testng.annotations.Test;
public class FlexibleTest {
@ObjectFactory
public IObjectFactory getObjectFactory() {
return new PowerMockObjectFactory();
}
@Test
@PrepareForTest(StaticUtils.class)
public void testWithPowerMock() {
// PowerMock enabled for this method only
}
@Test
public void regularTest() {
// Standard TestNG test
}
}Pattern 2: Class-level PowerMock
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockObjectFactory;
import org.testng.IObjectFactory;
import org.testng.annotations.ObjectFactory;
@PrepareForTest({StaticClass1.class, StaticClass2.class})
public class PowerMockTest {
@ObjectFactory
public IObjectFactory getObjectFactory() {
return new PowerMockObjectFactory();
}
// All test methods have PowerMock enabled
}Pattern 3: Mixed approach
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.annotations.Test;
@PrepareForTest(CommonStaticClass.class)
public class MixedTest extends PowerMockTestCase {
@Test
@PrepareForTest(SpecialStaticClass.class) // Additional classes for this method
public void specialTest() {
// Both CommonStaticClass and SpecialStaticClass prepared
}
}This module requires the following dependencies to be present:
Required (automatically included):
Optional (for additional functionality):
Transitive dependencies (handled automatically):
Common error scenarios and solutions:
Missing PowerMock ObjectFactory:
IllegalStateException: Missing org.powermock.modules.testng.PowerMockObjectFactory in classpathSolution: Ensure powermock-module-testng is in test classpath
Runtime Creation Errors:
RuntimeException: Cannot create a new instance of test classSolution: Check that test class has accessible constructor and PowerMock annotations are correct
ClassLoader Issues:
Tests may fail if PowerMock classloader conflicts with other bytecode manipulation. Use method-level @PrepareForTest to minimize scope when needed.