問題: PowerMock のインストルメンテーション クラスが初期化されていません。@Rule アノテーションを使用してライブラリをロードしています。VM 引数を配置しました: -javaagent:project_path/libs/powermock-module-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 プロジェクトです)。