2008年4月25日金曜日

Javaでprivateなインスタンス変数にアクセスする方法

よくJUnitなどを使ってテストのテストケースでprivate変数の値をテストしたい場合があるけど、テストのためにクラス設計を変更するはあんましよくないし、回りまわって得られた結果でおkとするのもめんどくさいと思うことがよくあります。
そんなときはアクセス権を動的に変更して、private変数に直接アクセスしちゃいましょう!
こちらを参考にしました。

クラス Field
リフレクションの学習

サンプルコード:


// Test.java
public class Test {
public static main(String[] args) {
PrivateVariable pv = new PrivateVariable();
// System.out.print(pv.himitu);
// ↑このコードはprivateの変数を呼び出してるのでコンパイルエラー
  Field field = pv.getClass().getDeclaredField("himitu");
// ↑対象のオブジェクトからクラスをとってgetDeclaredField()を使ってprivate変数を取得しています。渡している文字列は変数名です。
field.setAccessible(true);
// ↑取得したFieldオブジェクトのアクセスチェックするしないの指定。
//trueを渡すとアクセスチェックが抑制され、private変数も呼び出せるようになる。
System.out.print(field.get(pv));
// ↑Fieldオブジェクトにprivate変数があるオブジェクトを渡して値を取得する。
}
}

// PrivateVariable.java
public class PrivateVariable {
private String himitu = "実は俺・・・";
}


上記のコードを実行するとコンソールに「実は俺・・・」と表示され、PrivateVariableクラスのprivate変数himituにアクセスできたことがわかります。
これでいちいち回りくどいユニットテストを書かずに、private変数にアクセスして単純なテストケースを書けるようになりました!

※注意事項
private変数にはアクセサ(private変数にアクセスするメソッド。要するにゲッター、セッター。)が用意されている場合この方法ではなくてアクセサを通して得た値でテストをしてください。アクセサのなかにはテストしたいオブジェクトの状態を持つprivate変数の値に影響を与えている物もあるからです。

0 件のコメント: