PowerMockを使用したプライベートメソッドのモック
1. 概要
単体テストの課題の1つは、プライベートメソッドのモックです。
このチュートリアルでは、JUnitとTestNGでサポートされているPowerMockライブラリを使用してこれを実現する方法について学習します。
PowerMock integrates with mocking frameworks like EasyMock and Mockito and is meant to add additional functionality to these – such as mocking private methods, final classes, and final methods,など
これは、バイトコード操作と完全に独立したクラスローダーに依存することで実現します。
2. Mavenの依存関係
3. 例
LuckyNumberGenerator.の例から始めましょうこのクラスには、ラッキーナンバーを生成するための単一のパブリックメソッドがあります。
public int getLuckyNumber(String name) {
saveIntoDatabase(name);
if (name == null) {
return getDefaultLuckyNumber();
}
return getComputedLuckyNumber(name.length());
}
4. プライベートメソッドのモックのバリエーション
メソッドの徹底的な単体テストを行うには、プライベートメソッドをモックする必要があります。
4.1. 引数はないが戻り値があるメソッド
簡単な例として、引数のないプライベートメソッドの動作をモックし、目的の値を返すように強制しましょう。
LuckyNumberGenerator mock = spy(new LuckyNumberGenerator());
when(mock, "getDefaultLuckyNumber").thenReturn(300);
この場合、プライベートメソッドgetDefaultLuckyNumberをモックし、300の値を返すようにします。
4.2. 引数と戻り値を持つメソッド
次に、引数を使用してプライベートメソッドの動作をモックし、目的の値を返すように強制します。
LuckyNumberGenerator mock = spy(new LuckyNumberGenerator());
doReturn(1).when(mock, "getComputedLuckyNumber", ArgumentMatchers.anyInt());
この場合、プライベートメソッドをモックし、1を返します。
入力引数は気にせず、ワイルドカードとしてArgumentMatchers.anyInt()を使用することに注意してください。
4.3. メソッドの呼び出しの検証
最終的な戦略は、PowerMockを使用してプライベートメソッドの呼び出しを検証することです。
LuckyNumberGenerator mock = spy(new LuckyNumberGenerator());
int result = mock.getLuckyNumber("Tyranosorous");
verifyPrivate(mock).invoke("saveIntoDatabase", ArgumentMatchers.anyString());
5. 注意の言葉
最後に、プライベートメソッドはPowerMockを使用してテストできますが、we must be extra cautious while using this technique.
テストの目的はクラスの動作を検証することであるため、ユニットテスト中にクラスの内部動作を変更しないでください。
モック手法は、クラス自体ではなく、クラスの外部依存関係に適用する必要があります。
クラスをテストするためにプライベートメソッドのモックが不可欠な場合、通常は設計が悪いことを示しています。
6. 結論
この簡単な記事では、PowerMockを使用してMockitoの機能を拡張し、テスト対象クラスのプライベートメソッドのモックと検証を行う方法を示しました。
このチュートリアルのソースコードはover on GitHubにあります。