PowerMock - @PrepareForTest上的NPE

时间:2012-12-14 19:03:48

标签: java powermock

问题:PowerMock中的检测类未初始化。我正在通过@Rule注释加载库。我已经有了VM参数: -javaagent:project_path /库/ powermock模块-javaagent-1.5.jar

当我使用调试器时,会调用PowerMockAgent #premain并设置检测对象,但是在测试设置期间调用它时,检测对象为null,抛出下面的错误。

为什么在调用PowerMockAgent #premain和PowerMockClassRedefiner.redefine调用它时,检测变量之间没有保持它的值?

在加载时,仪器设置正确:

  private static void initialize(String agentArgs, Instrumentation inst) throws IOException {
    instrumentation = inst;
    inst.addTransformer(new DefinalizingClassTransformer(), false);
    inst.addTransformer(classTransformer, true);
}

但是从@PrepareForTest({Logger.class})再次调用时,为null

public class PowerMockClassRedefiner {

public static void redefine(Class<?> cls) {
    if(cls == null) {
        throw new IllegalArgumentException("Class to redefine cannot be null");
    }

    PowerMockAgent.getClasstransformer().setClassesToTransform(Arrays.asList(cls.getName()));

    try {            
        PowerMockAgent.instrumentation().retransformClasses(cls);
    } catch(Exception e){
        throw new RuntimeException("Failed to redefine class "+cls.getName(), e);
    }
}

导致错误:

java.lang.RuntimeException: Failed to redefine class com.testapp.Logger
at org.powermock.modules.agent.PowerMockClassRedefiner.redefine(PowerMockClassRedefiner.java:33)
at org.powermock.modules.agent.PowerMockClassRedefiner.redefine(PowerMockClassRedefiner.java:42)
at com.testapp.testFramework.PowerMockRuleAgentSetup.redefine(PowerMockRuleAgentSetup.java:29)
at com.testapp.testFramework.PowerMockRuleAgentSetup.initialize(PowerMockRuleAgentSetup.java:19)
at com.testapp.testFramework.PowerMockOverriderRule.apply(PowerMockOverriderRule.java:19)
at org.junit.runners.BlockJUnit4ClassRunner.withMethodRules(BlockJUnit4ClassRunner.java:341)
at org.junit.runners.BlockJUnit4ClassRunner.withRules(BlockJUnit4ClassRunner.java:330)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:248)
at com.xtremelabs.robolectric.RobolectricTestRunner.methodBlock(RobolectricTestRunner.java:287)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.NullPointerException
at org.powermock.modules.agent.PowerMockClassRedefiner.redefine(PowerMockClassRedefiner.java:31)
... 22 more

这是我的测试设置:

@RunWith(RobolectricTestRunner.class)
@PrepareForTest({ Logger.class })  // THIS IS WHERE THE ERROR GETS THROWN
public class LoggerTest {
@Rule public PowerMockOverriderRule rule = new PowerMockOverriderRule();
public LoggerConfig config;

@Before
public void setUp() {
    config = mock(LoggerConfig.class);
}

更新: 删除@RunWith(RobolectricTestRunner.class)可以解决问题,但不能解决我的项目问题。 (这是一个Android项目)。

1 个答案:

答案 0 :(得分:0)

我很抱歉,但为什么你甚至想要模拟一个Logger类呢?如果要确保将输出记录到控制台,可以将记录器包装在可以模拟的抽象中。

class LogWraper {
   void someMethod() {
     logger.log()
   }
}

然后你可以创建一个你的FooWraper模拟器。根本不需要使用Powermock ......