社内se × プログラマ × ビッグデータ

プログラミングなどITに興味があります。

Java private フィールドをモックする

private フィールドをモックする junit 書きたいなと思って調べたら、すぐに出てきたのが mockito の whitebox.
以前使ったことがあった気がするけど、忘れていました。

とりあえず簡単なサンプルで
public class WhiteBoxExample {
	
	private String message = "This is example.";
	
	public WhiteBoxExample() {
	}
	
	public String getMessage() {
		return message;
	}
}

これの message 変数に格納されている内容を書き換えるということです。

junit の方は
public class WhiteBoxExampleTest {

        // 1つ目は何もせずに、そのまま出力させるテスト
	@Test
	public void testWithoutWhiteBox() {
		WhiteBoxExample wb = new WhiteBoxExample();
		assertTrue(wb.getMessage().equals("This is example."));
	}

        // 2つ目は whitebox を使って、値を書き換えてます
	@Test
	public void testWithWhiteBox() {
		WhiteBoxExample wb = new WhiteBoxExample();
		Whitebox.setInternalState(wb, "message", "overwritten the message.");
		
		assertTrue(wb.getMessage().equals("overwritten the message."));
	}
}

Whitebox.setInternalState(対象クラスのインスタンス, "モックするフィールド名", 置き換える値);
たったこれだけで private フィールドが置き換わってしまいました。
非常に強力なライブラリだと思いますが、何でも置き換えてしまうと、本来の仕様に沿ったテストから遠ざかってしまう気がします。
テストのコア部分を置き換えるのではなくて、そこに到達するまでのあくまで補助的に使った方が良いですね。
そもそも頼らないでテスト出来るように設計出来れば良いのかもしれませんが。