JUnitに限った話では無いですが、外部からリフレクションを使ってprivateメソッドにアクセスするメモです。
※ソースコードはJUnit4の例です。
privateメソッドにアクセス
テスト対象
まず、適当にテスト対象のクラスを作ってみます。
package dammy;
public class Main {
//プライベートフィールド
private String name;
//初期化
Main(){
name = "プライベート";
}
//プライベートメソッド
private int privateMethod(int in){
return in * 2;
}
//プロテクテッド
protected int protectedMethod(int in){
return in * 3;
}
//パブリック
public int publicMethod(int in){
return in * 4;
}
}
処理としては何も意味なしなので気にしないでください。
リフレクションでアクセス
public class MainTest {
private Main obj;
@Before
public void setUp() throws Exception {
obj = new Main();
}
@After
public void tearDown() throws Exception {
obj = null;
}
//日本語でメソッド名書くとわかりやすい
@Test
public void プライベート変数を参照() throws Exception{
//名前を指定して取得
Field field = Main.class.getDeclaredField("name");
//アクセス権限を与える
field.setAccessible(true);
//指定のインスタンス内のfieldを取得
assertEquals("プライベート", (String)field.get(obj));
}
@Test
public void プライベートメソッドを実行() throws Exception {
//名前と引数を指定して取得
Method method = Main.class.getDeclaredMethod("privateMethod", int.class);
method.setAccessible(true);
assertEquals(2,method.invoke(obj, 1));
}
}
-
getDeclaredField()/Method()
で取得 -
setAccessible()
でアクセス可能にする -
invoke
で対象のインスタンス指定して実行
でOKです。
protectedはビルドパスで設定すると楽
テストコードからprotectedなメソッドにアクセスする場合、最も楽なのはテスト対象と同じパッケージに入れることですが、それはそれでソースコード管理が煩雑になります。
テスト用のコードを別ディレクトリ内に作成しておき、ビルドパスの設定でソースコードと一緒に指定しておくことで同一パッケージにあるように扱うことができます。
図はEclipseの例
@Test
public void プロテクテッドメソッド(){
//直接参照可能
assertEquals(3, obj.protectedMethod(1));
}