Spring Testでprivateなフィールドの値を設定する

こんにちは、さるまりんです。

Spring Testでprivate(privateでなくても非公開)なフィールドに値を設定してテストしたい時にどうしようというお話です。

例えばこんなクラスがあります。

SomeClassクラス

public class SomeClass {

	/** インスタンスが生成されたタイムスタンプ */
	private long bornAt;
	
	/**
	 * コンストラクター
	 */
	public SomeClass() {
		// 生成されたタイムスタンプを設定
		this.bornAt = new Date().getTime();
	}
	
	/**
	 * 生成されたタイムスタンプを取得
	 * @return インスタンス生成時のタイムスタンプ (long)
	 */
	public long getBornAt() {
		return this.bornAt;
	}
}

bornAtの値はインスタンス生成時に設定されて、setterが用意されていないので変更することができません。

が、テストする際にこの値を変えたいケースが出てきたとします。

そんなときに利用できるのがReflectionTestUtils.setField()メソッドです。

呼び方は

ReflectionTestUtils.setField(対象オブジェクトの変数, "フィールド名", 設定する値)

です。

テストメソッドでの呼び出し例です。

@Test
public void testBornAt() throws InterruptedException {
	
	SomeClass obj = new SomeClass();
	long now = new Date().getTime();
	
	ReflectionTestUtils.setField(obj, "bornAt", now + 1000);
	
	assertThat(obj.getBornAt(), greaterThan(now));
}

テストではobjが1秒先の未来に生成されたとしてテストを実行しています。

ReflectionTestUtils.setField(obj, "bornAt", now + 1000);

このコードで変数objbornAtフィールドに1000ミリ秒先の値を設定しています。

上の例は簡単なものですが、いろんなケースで値を設定する必要が出てくるかなと思います。

privateに値を設定とかどうしたらいいのか悩んでいたのでこんな方法があってびっくりです。

テスト、しっかりやらないとですね。

読んでくださってありがとうございます。

ではまた!