JUnit テストのコンストラクターをprivate static final
持つクラスにフィールドを設定しようとしています。private
コードを基本まで煮詰めると、次のようになります。
public class Foo {
private static final boolean FLAG = false;
private Foo() { /* don't call me */ }
public static boolean get() { return FLAG; }
}
私のテストは次のようになります。
@RunWith(PowerMockRunner.class)
@PrepareEverythingForTest // Whitebox fails without this line
public class FooTest {
@Test
public void testGet() {
Whitebox.setInternalState(Foo.class, "FLAG", true);
assertTrue(Foo.get());
}
}
そして、これが私のPOMファイルからの抜粋です。
<junit.version>4.11</junit.version>
<powermock.version>1.5.4</powermock.version>
<mockito.version>1.9.5</mockito.version>
にブレークポイントを設定すると、IntelliJ のデバッガーでに設定されreturn FLAG;
ていることがはっきりとわかります。それでも、テストは で失敗します。FLAG
true
AssertionError
これを機能させるために何をすべきか考えていますか?
更新:リフレクションの使用も機能しないようです:
@Test
public void testGet_usingReflection() throws Exception {
setField(Whitebox.invokeConstructor(Foo.class), "FLAG", true);
assertTrue(Foo.get());
}
public static void setField(Object targetObject, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException {
Class clazz = targetObject.getClass();
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
Field modifiers = Field.class.getDeclaredField("modifiers");
modifiers.setAccessible(true);
modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(targetObject, value);
}
このsetField()
方法は、内部ライブラリから入手できるものです。残念ながら、同じ結果が得られます。AssertionError
更新 2: PowerMock を完全に削除してもあまり効果がないようです。
@Test
public void testGet_usingReflectionWithoutPowerMock() throws Exception {
setField(Foo.class.getDeclaredField("FLAG"), true);
assertTrue(Foo.get());
}
public static void setField(Field field, Object value) throws NoSuchFieldException, IllegalAccessException {
field.setAccessible(true);
Field modifiers = Field.class.getDeclaredField("modifiers");
modifiers.setAccessible(true);
modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, value);
}
このために、クラスレベルから PowerMock アノテーションを削除しました...
また、この質問をPowerMock メーリング リストにも投稿しました。