web-dev-qa-db-ja.com

JUnit、EasyMock、PowerMockを使用して静的な最終変数をモックする方法

JUnit、EasyMock、またはPowerMockを使用して、i18nクラスをモックするだけでなく、静的なfinal変数をモックしたいです。それ、どうやったら出来るの?

23
Prince

モッキング変数のようなものはありますか?再割り当てと呼びます。 EasyMockまたはPowerMockがstatic finalフィールドを再割り当てする簡単な方法を提供するとは思わない(奇妙なユースケースのように聞こえる)。

それをしたい場合は、おそらくデザインに何か問題があります。変数がテスト目的であっても別の値を持つ可能性があることがわかっている場合は、static final(またはより一般的なグローバル定数)を避けてください。

とにかく、リフレクションを使用してそれを達成できます( リフレクションを使用して、単体テスト用の静的な最終File.separatorCharを変更しますか? ):

static void setFinalStatic(Field field, Object newValue) throws Exception {
    field.setAccessible(true);

    // remove final modifier from field
    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

    field.set(null, newValue);
}

次のように使用します。

setFinalStatic(MyClass.class.getField("myField"), "newValue"); // For a String

破棄するときにフィールドを元の値にリセットすることを忘れないでください。

41
Antoine

PowerMock機能の組み合わせを使用して実行できます。 @PrepareForTest({...})アノテーションを使用して静的モックを作成し、フィールドをモックし(Mockito.mock(...)を使用していますが、同等のEasyMockコンストラクトを使用できます)、WhiteBox.setInternalState(...)メソッドを使用して値を設定します。これは、変数がprivateであっても機能することに注意してください。

拡張された例については、このリンクを参照してください: http://codyaray.com/2012/05/mocking-static-Java-util-logger-with-easymocks-powermock-extension

5
cwash