ITコンサルの日常

ITコンサル会社に勤務する普通のITエンジニアの日常です。

JMockitでprivate static finalな定数を書き換える

設定ファイルにするまでもないものは定数で定義したりしますが、違う値でテストしたいときがあります。
jmockitを使うと(使わなくても)簡単にできるのですが、一点ワナがあったのでメモしておきます。

テスト対象クラス(Hello.java

public class Hello {
	private static final int HELLO_CONSTANTS_PRIMITIVE_TYPE = 100;
	private static final Integer HELLO_CONSTANTS_REFERENCE_TYPE = 100;

	public static void printHelloConstants() {
		System.out.println(HELLO_CONSTANTS_PRIMITIVE_TYPE);
		System.out.println(HELLO_CONSTANTS_REFERENCE_TYPE);
	}
}

プリミティブ型の定数と、リファレンス型の定数がそれぞれあります。

テストクラス(HelloTest.java

import mockit.Deencapsulation;
import mockit.integration.junit4.JMockit;

import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(JMockit.class)
public class HelloTest {
	@Test
	public void testPrintHelloConstants() {
		Deencapsulation.setField(Hello.class, "HELLO_CONSTANTS_PRIMITIVE_TYPE", 1000);
		Deencapsulation.setField(Hello.class, "HELLO_CONSTANTS_REFERENCE_TYPE", 1000);
		Hello.printHelloConstants();
	}
}

JMockitのリフレクションユーティリティである、DeencapsulationクラスのsetFieldメソッドを呼ぶことで書き換えできます。
が、結果は以下の通リです。

結果


100
1000

というわけで、最強と言われるJMockitでも、プリミティブ型の定数までは書き換えできないということのようです。