前回に引き続きjMockitのお話で、今回はテスト対象クラス自身のメソッドを一部モック化するお話です。
部分的なモッキング (Partial Mocking)
public class Hoge {
public String getFullName() {
return getFirstName() + " " + getLastName();
}
public String getFirstName() {
return this.fName;
}
public String getLastName() {
return this.lName;
}
}
Hoge hoge = new Hoge();
new Verifications(hoge) {{
hoge.getFirstName(); result="ホゲ山";
hoge.getLastName(); result="ほげ二郎";
}}
assertThat(hoge.getFullName(), is("ホゲ山 ほげ二郎"));
テスト対象のクラスのメソッド同士に依存関係があるときに、対象メソッド単体でテストすることが可能です。
例だとgetFirstName() ,getLastName() はごく単純ですが、これがとても複雑な場合にはモック化する価値があります。
部分的なモッキング (Partial Mocking) private な場合
先の例ではgetFirstName() ,getLastName()がTestクラスからアクセス可能なスコープでしたが、privateな場合もありますよね。
テストの為だけにメソッドのスコープをデフォルトスコープにする手もありますが、本来的にprivateなのにそれを歪めるというのも嫌なものです。
jMockitの場合、privateメソッドの挙動もモック化できます。
http://jmockit.googlecode.com/svn/trunk/www/tutorial/BehaviorBasedTesting.html#deencapsulation
public class Hoge {
public String getFullName() {
return getFirstName() + " " + getLastName();
}
private String getFirstName() {
return this.fName;
}
private String getLastName() {
return this.lName;
}
}
import static mockit.Deencapsulation.*;
Hoge hoge = new Hoge();
new Verifications(hoge) {{
invoke(hoge ,"getFirstName"); result="ホゲ山";
invoke(hoge ,"getLastName"; result="ほげ二郎";
}}
assertThat(hoge.getFullName(), is("ホゲ山 ほげ二郎"));
このDeencapsulationというクラスのstaticメソッドが鍵です。
privateメソッドに対するテストもかける
上記のDeencapsulationを使うとprivateメソッドに対するassertも書くことができます。
import static mockit.Deencapsulation.*;
Hoge hoge = new Hoge();
assertThat(invoke(hoge ,"getFirstName"), is("ホゲ山"));
assertThat(invoke(hoge ,"getLastName"), is("ほげ二郎"));
ちなみにFirstName ,LastNameの設定間違えてますが疲れたのでまあいいや。