Java测试框架系列:PowerMock使用系列-8:委托给其他Runner和使用引导程序

2,279 阅读3分钟

一:使用 @PowerMockRunnerDelegate

   从PowerMock 1.6.0可用的功能。

从PowerMock 1.6.0版本以来,支持将测试执行委托给另一个JUnit runner而不使用JUnit Rule. 这将实际的测试执行留给您选择的另一个runner。 例如,测试可以委托给“SpringJunit4ClassRunner”,“Parameterized”或“Enclosed”runner。 用法示例:

@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(Parameterized.class)
@PrepareForTest({FinalDemo.class, PrivateFinal.class})
public class FinalDemoTest {

    @Parameterized.Parameter(0)
    public String expected;

    @Parameterized.Parameters(name = "expected={0}")
    public static Collection<?> expections() {
        return java.util.Arrays.asList(new Object[][]{
            {"Hello altered World"}, {"something"}, {"test"}
        });
    }

    @Test
    public void assertMockFinalWithExpectationsWorks() throws Exception {
        final String argument = "hello";

        FinalDemo tested = mock(FinalDemo.class);

        when(tested.say(argument)).thenReturn(expected);

        final String actual = "" + tested.say(argument);

        verify(tested).say(argument);

        assertEquals("Expected and actual did not match", expected, actual);
    }
}

参考

二:使用 JUnit Rule 引导程序

从 PowerMock 1.4 时功能可用。

从 1.4 版开始,可以使用 JUnit Rule 而不是使用 PowerMockRunner 和 RunWith 注解来引导 PowerMock 。这允许您在使用其他 JUnit 运行程序的同时仍然受益于 PowerMock 的功能。您可以通过指定:

@PrepareForTest(X.class);
public class MyTest {
    @Rule
    PowerMockRule rule = new PowerMockRule();

    // Tests goes here
    ...
}

和 Maven 一起使用 PowerMockRule

你需要依赖这些项目:

<dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-module-junit4-rule</artifactId>
  <version>2.0.2</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-classloading-xstream</artifactId>
  <version>2.0.2</version>
  <scope>test</scope>
</dependency>

您还可以替换powermock-classloading-xstream为 Objenesis 版本:

<dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-classloading-objenesis</artifactId>
  <version>2.0.2</version>
  <scope>test</scope>
</dependency>

然而,这个版本不如 xstream 版本稳定,但它不需要任何额外的依赖项。

警告:使用版本 PowerMock 1.4(或更高版本),因为在此版本之前,该Rule实际上并未执行任何测试方法(但看起来确实如此)。

不和 Maven 一起使用 PowerMockRule

您需要下载powermock-module-junit4-rulepowermock-classloading-basepowermock-classloading-xstreampowermock-classloading-objenesis 之一,并将其放入您的类路径中。

参考

三:使用 Java 代理引导启动

使用 Java 代理引导启动

   从 PowerMock 1.4.9 时功能可用

从 1.4.9 版本开始,可以使用 Java 代理而不是使用 PowerMockRunner 和 RunWith 注解来引导 PowerMock。这允许您使用例如其他 JUnit 运行程序,同时仍然受益于 PowerMock 的功能。基于代理的引导程序和基于类加载的引导程序之间的主要区别在于,在使用 XML 框架等时不会遇到类加载问题。建议在使用 PowerMock 对系统的较大部分进行集成测试时使用这种引导方式。

JUnit

To bootstrap the Agent in JUnit you can use the PowerMockRule in the powermock-module-junit4-rule-agent project. For example:

要在 JUnit 中引导代理,您可以在powermock-module-junit4-rule-agent项目中使用PowerMockRule 。例如:

@PrepareForTest(X.class);
public class MyTest {
     @Rule
     PowerMockRule rule = new PowerMockRule();

     // Tests goes here
     ...
}

在某些情况下,可能需要在运行测试之前手动启动代理。你可以使用:

public class MyTest {
   static {
       PowerMockAgent.initializeIfNeeded();
   }

   ..
}

It's recommended that you put powermock-module-junit4-rule-agent before junit in the classpath.

建议您将powermock-module-junit4-rule-agent 在JUnit之前放在类路径中。

TestNG

To bootstrap the Agent in TestNG you should extend from PowerMockTestCase in the powermock-module-testng-common project and you need to have the jar file from powermock-module-testng-agent in classpath. For example:

@PrepareForTest(X.class)
public class SomeTest extends PowerMockTestCase {
    ...
}

Maven

JUnit

<dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-module-junit4-rule-agent</artifactId>
  <version>2.0.2</version>
  <scope>test</scope>
</dependency>

TestNG

<dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-module-testng-agent</artifactId>
  <version>2.0.2</version>
  <scope>test</scope>
</dependency>

在 Maven 中预先加载 PowerMock 代理

在某些情况下(例如mock最终类),可能需要在 Maven 中急切地加载 PowerMock 代理,以便测试在 Surefire 中工作。如果您遇到这种情况,请将以下内容添加到您的 pom.xml 中:

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <argLine>
                        -javaagent:${settings.localRepository}/org/powermock/powermock-module-javaagent/2.0.2/powermock-module-javaagent-2.0.2.jar
                    </argLine>
                    <useSystemClassloader>true</useSystemClassloader>
                </configuration>
            </plugin>
        </plugins>
</build>  

非 Maven 用户

You need to download powermock-java-agent (source, javadoc) and either powermock-module-junit4-rule-agent (sources, javadoc) if using JUnit or powermock-module-testng-agent (sources, javadoc) if using TestNG.

你需要下载 powermock-java-agent (source, javadoc) ;如果使用JUnit,还需要powermock-module-junit4-rule-agent (sources, javadoc) 如果使用TestNG,还需要powermock-module-testng-agent (sources, javadoc)。

JUnit

在 Eclipse 中使用 JUnit 预先加载 PowerMock 代理

要使用 Eclipse 和 JUnit 急切地加载 PowerMock 代理,您必须首先进入“运行配置”对话框并添加以下 JVM 参数:

-javaagent: <jarpath>/powermock-module-javaagent-2.0.2.jar

接下来,您还必须确保将 powermock-module-javaagent-2.0.2.jar 放在运行配置的类路径中,在默认类路径之前(这是为了确保代理在 junit 之前加载)。

当前的已知的限制

  • 无法抑制静态初始化代码块
  • 无法更改静态final字段的值

参考