主に自分が不甲斐ないせいでJavaを2週間くらい放置していたのですが、開発も佳境に突入しいざJUnitでテストすんべ!と奮い立ち、アクセス修飾子がPrivateのメソッドやフィールド変数を使おうとしても当然のごとく他クラスからは呼べないわけで( ^ω^)・・・
でもまぁいろいろ調べてみたらできちゃったのでメモっておきます。
よかったら肥やしにしてみてください。
使用環境:
OS:Windows 10
java ver:8
IDE:eclipse 4.6 Neon
Jarファイルをダウンロードしよう
外部サイト(https://ja.osdn.net/projects/sfnet_junit-addons/releases/)
からjunit-addonsのJarファイルを入手します。
てきとーなローカルディレクトリに保存してください。
Jarファイルを追加しよう
eclipseを起動し、[パッケージ・エクスプローラ]上で右クリックし、[ビルド・パス]→[ビルドパスの構成]→[javaのビルド・パス]から外部Jarを追加します。
これで準備完了。
ちなみにAPI仕様はどんな感じ?
ふむふむ。
さっぱりわかんねぇ。
おしえてぐーぐるせんせー!
ごちゃごちゃ動かす
テストプログラムを用意します。
まずはテスト対象のプログラムから。
public class Sample {
// privateなフィールド変数
private int x = 10;
// privateでstaticなフィールド変数
private static int y = 20;
// privateなメソッド
private String testMethod(String x){
return x;
}
// privateでstaticなメソッド
private static String testStaticMethod(String y, String z){
return y + z;
}
}
次にJUnit用にクラスファイルを用意します。
import static org.junit.Assert.*;
import org.junit.Test;
import junitx.util.PrivateAccessor;
public class SampleTest {
@Test
/**
* privateのフィールド、メソッドにアクセスするテスト関数
*/
public void privateGetField() throws Throwable {
Sample sample = new Sample();
try {
// privateなフィールド変数にアクセスするためのメソッド。
// 第一引数:テスト対象クラスのインスタンス変数 第二引数:アクセスしたいフィールド変数名
int x = (int)PrivateAccessor.getField(sample, "x");
// アサーションにより実測値と期待値を比較
assertEquals(x,10);
// privateでstaticなフィールド変数も同様の手法でアクセスできる。説明省略
int y = (int)PrivateAccessor.getField(sample, "y");
assertEquals(y,20);
// privateな関数にアクセスするためのメソッド。
// 第一引数:テスト対象クラスのインスタンス変数 第二引数:アクセスしたいフィールド関数名
// 第三引数:引数の型の配列 第四引数:引数の値の配列
String method_x = (String)PrivateAccessor.invoke( sample,
"testMethod",
new Class[]{String.class},
new Object[]{"private_x"});
assertEquals(method_x,"private_x");
// privateでstaticな関数も同様の手法でアクセスできる。引数の型の数に応じて第三、第四引数を工夫すること
String method_y = (String)PrivateAccessor.invoke( sample,
"testStaticMethod",
new Class[]{String.class,String.class},
new Object[]{"private_","static_y"});
assertEquals(method_y,"private_static_y");
} catch (NoSuchFieldException e) {
e.printStackTrace();
}finally{
}
}
}
実行
どや!
できた!
おまけ
privateなフィールド変数に値をセットすることもできちゃったり。
//途中省略
@Test
/**
* privateなフィールド変数に値をセットする関数
*/
public void privateSetField(){
Sample sample = new Sample();
try {
// 第一引数:テスト対象クラスのインスタンス変数 第二引数:変数の名前
// 第三引数: セットしたい値
PrivateAccessor.setField(sample, "x", 100);
// セットできたか確認!
int get_x = (int)PrivateAccessor.getField(sample, "x");
assertEquals(get_x,100);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}finally{
}
}
おわりっ