sometimes we need to test final class or static class, at this time we need powermock.
1, update pom.xml to import powermock
<dependency> <groupId>org.powermock</groupId> <artifactId>powermock-core</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito</artifactId> <scope>test</scope> </dependency>
2. then we can use powermock in unit test like below:
in this example, ReadInputRegistersResponse is a final class.
@RunWith(PowerMockRunner.class) @PrepareForTest(ReadInputRegistersResponse.class) public class InverterDetailsResponseTest { private ReadInputRegistersResponse mockModbusResp; @test public void test1() { mockModbusResp = mock(ReadInputRegistersResponse.class); // ...... }
but sometimes in unit test, we need have @RunWith(SpringJUnit4ClassRunner.class), when we still need powermock, we will avoid @RunWith(PowerMockRunner.class).
below is the example how to avoid @RunWith(PowerMockRunner.class), but still use powermock.
1. it is simple , just add : PowerMockAgent.initializeIfNeeded() method.
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"/inverter-persistent-config.xml"}) public class TcpModbusServiceTest extends AbstractInverterTest { static { PowerMockAgent.initializeIfNeeded(); } }
Note:
at this time the mocked class should be a local variable like this:
private void mockModbusResponse() throws CommunicationException { ReadInputRegistersResponse mockModbusResp = mock(ReadInputRegistersResponse.class); // ... ... ... }
2. if you are using maven and want to run test by mvn test, then you need to add below lines in build config as well:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.4</version> <configuration> <excludes> <exclude>**/*IT.java</exclude> <exclude>**/Abstract*.java</exclude> </excludes> <argLine> -javaagent:${settings.localRepository}/org/powermock/powermock-module-javaagent/${powermock.version}/powermock-module-javaagent-${powermock.version}.jar </argLine> <useSystemClassloader>true</useSystemClassloader> </configuration> </plugin> </plugins> </build>
3. in pom.xml dependency is a bit different:
<dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4-rule-agent</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock.tests</groupId> <artifactId>powermock-tests-utils</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-core</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito</artifactId> <scope>test</scope> </dependency>
that's it.