JMockitを使った擬似静的メソッド
1概要
MockitoおよびEasymock
などの人気のあるモックライブラリは、Javaの継承ベースのクラスモデルを利用してモックアップを生成します。
EasyMock
は実行時にインタフェースを実装しますが、
Mockito
はモックスタブを作成するためにターゲットクラスから継承します。
静的メソッドはクラスに関連付けられ、オーバーライドすることはできないため、どちらのアプローチも静的メソッドには適しません。ただし、** JMockitは静的メソッドのモック機能を提供します。
このチュートリアルでは、これらの機能のいくつかについて説明します。
JMockitの紹介については、https://www.baeldung.com/jmockit-101[以前の記事]を参照してください。
2 Mavenの依存関係
Mavenの依存関係から始めましょう。
<dependency>
<groupId>org.jmockit</groupId>
<artifactId>jmockit</artifactId>
<version>1.24</version>
<scope>test</scope>
</dependency>
これらのライブラリの最新版はhttps://search.maven.org/classic/#search%7C1%7Ca%3A%22jmockit%22[Maven Central]にあります。
3非静的メソッドから呼び出される静的メソッド
まず、静的メソッドに内部的に依存する非静的メソッドを持つクラスがある場合を考えてみましょう。
public class AppManager {
public boolean managerResponse(String question) {
return AppManager.isResponsePositive(question);
}
public static boolean isResponsePositive(String value) {
if (value == null) {
return false;
}
int length = value.length();
int randomNumber = randomNumber();
return length == randomNumber ? true : false;
}
private static int randomNumber() {
return new Random().nextInt(7);
}
}
それでは、メソッド
managerResponse()をテストしましょう。その戻り値は他のメソッドに依存するので、
isResponsePositive()__メソッドをモックする必要があります。
この静的メソッドは、
JMockitの匿名クラス
mockit.MockUp.MockUp <T>
(Tはクラス名になります)および
@ Mock
__アノテーションを使ってモックすることができます。
@Test
public void givenAppManager__whenStaticMethodCalled__thenValidateExpectedResponse() {
new MockUp<AppManager>() {
@Mock
public boolean isResponsePositive(String value) {
return false;
}
};
assertFalse(appManager.managerResponse("Some string..."));
}
ここでは、テストに使用したい戻り値で
isResponsePositive()
を偽装しています。したがって、Junit-5で提供されているhttps://www.baeldung.com/junit-5-preview#new[
Assertions
]ユーティリティを使用して予想される結果を確認します。
4プライベート静的メソッドのテスト
いくつかのケースでは、他のメソッドはクラスのプライベート静的メソッドを使用します。
private static Integer stringToInteger(String num) {
return Integer.parseInt(num);
}
そのようなメソッドをテストするには、
プライベート静的メソッドをモックする必要があります
。
JMockit
が提供する
__Deencapsulation.invoke()
__utilityメソッドを使用できます。
@Test
public void givenAppManager__whenPrivateStaticMethod__thenValidateExpectedResponse() {
int response = Deencapsulation.invoke(AppManager.class, "stringToInteger", "110");
assertEquals(110, response);
}
名前が示すように、目的はオブジェクトの状態を__カプセル化解除することです。このように、JMockitは他の方法ではテストできなかったテスト方法を単純化します。
5結論
この記事では、
JMockit
を使用して静的メソッドをモックする方法を説明しました。 JMockitの高度な機能の詳細については、JMockitの高度な使用方法(https://www.baeldung.com/jmockit-advanced-usage)をご覧ください。
いつも通り、このチュートリアルの完全なソースコードはhttp://github.com/eugenp/tutorials/tree/master/testing-modules/mocks[GitHubで利用可能]です。