こんにちは、金子です。
最近JMockitを使う機会があったのですが、JMockitはバージョンによって大きく仕様が変わるため、今使用しているバージョンでの記述方法を探すのに苦労しました。
そこで今回は「メソッドの呼び出し確認方法」をテーマに、JMockitのバージョンによる書き方の違いをまとめました。
以下のクラスのpublicMethodメソッドの単体テストを行う場合を例に説明します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public class Sample {
public void publicMethod(boolean testFlg) {
callMethod1();
if(testFlg) {
callMethod2();
}
}
public void callMethod1() {
}
public void callMethod2() {
}
}
|
バージョン1.28以前の場合
呼び出し確認にはExpectationsの中で行う方法とMockUpの中で行う方法があります。
Expectations内で呼び出し確認を行う場合は、以下のフィールドを用いて呼び出し確認を行うことができます。
- times
- 呼び出される回数を指定する。指定回数の呼び出しでなければエラーとなる。
- minTimes
- 呼び出される最低回数を指定する。指定回数以下の呼び出しがあればエラーとなる。
- maxTimes
- 呼び出される最大回数を指定する。指定回数以上の呼び出しだとエラーとなる。
例として、バージョン1.22を利用した場合の書き方は次のようになります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/**
* JMockit ver1.22
* Expectationsでメソッド呼び出し確認
*/
@Test
public void testPublicMethod_001() {
Sample target = new Sample();
// 呼び出し確認
new Expectations(target) {{
// 最低1回呼ばれることの確認
target.callMethod1();
minTimes = 1;
// 最大0回呼ばれる(=呼ばれない)ことの確認
target.callMethod2();
maxTimes = 0;
}};
// テスト実行
target.publicMethod(false);
}
|
次に、MockUp内で呼び出し確認を行う方法です。
@Mockアノテーションに含まれる3つの属性を用いることで実現できます。
- invocations
- 呼び出される回数を指定する。指定回数の呼び出しでなければエラーとなる。
- minInvocations
- 呼び出される最低回数を指定する。指定回数以下の呼び出しがあればエラーとなる。
- maxInvocations
- 呼び出される最大回数を指定する。指定回数以上の呼び出しだとエラーとなる。
バージョン1.22を利用した場合の書き方は以下の通りです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
/**
* JMockit ver1.22
* MockUpでメソッド呼び出し確認
*/
@Test
public void testPublicMethod_002() {
Sample target = new Sample();
// 呼び出し確認
new MockUp<Sample>() {
// 最低1回呼ばれることの確認
@Mock(minInvocations = 1)
public void callMethod1() {
}
// 最大0回呼ばれる(=呼ばれない)ことの確認
@Mock(maxInvocations = 0)
public void callMethod2() {
}
};
// テスト実行
target.publicMethod(false);
}
|
しかし、これらの@Mockアノテーションの属性はバージョン1.26で非推奨となり、1.29で削除されました。
そのため、バージョン1.29以降では別の方法を取る必要があります。
バージョン1.29以降の場合
バージョン1.29以降でも、Expectations内で呼び出し確認を行う場合は1.28以前と同様のやり方で大丈夫です。
例として、バージョン1.45を利用した場合の書き方は次のようになります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/**
* JMockit ver1.45
* Expectationsでメソッド呼び出し確認
*/
@Test
public void testPublicMethod_001() {
Sample target = new Sample();
// 呼び出し確認
new Expectations(target) {{
// 最低1回呼ばれることの確認
target.callMethod1();
minTimes = 1;
// 最大0回呼ばれる(=呼ばれない)ことの確認
target.callMethod2();
maxTimes = 0;
}};
// テスト実行
target.publicMethod(false);
}
|
続いてMockUp内で呼び出し確認を行う方法ですが、
先述のとおりバージョン1.29以降では@Mockアノテーションの属性は使用できなくなっています。
結論から言うと、JMockitの機能ではMockUpで呼び出し確認を行うことはできません。
(2019/3/22現在で最新のバージョン1.45でも同様です)
しかし、どうしても呼び出し確認をMockUp内で行う必要がある場合は、
以下のように呼び出し用のカウンターを変数として用意する方法がよいかと思います。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
/**
* JMockit ver1.45
* MockUpでメソッド呼び出し確認
*/
@Test
public void testPublicMethod_002() {
Sample target = new Sample();
// 呼び出し確認用カウンター
AtomicLong callMethod1Counter = new AtomicLong();
AtomicLong callMethod2Counter = new AtomicLong();
// 呼び出し確認
new MockUp<Sample>() {
@Mock
public void callMethod1() {
callMethod1Counter.incrementAndGet(); // 呼ばれたらインクリメント
}
@Mock
public void callMethod2() {
callMethod2Counter.incrementAndGet(); // 呼ばれたらインクリメント
}
};
// テスト実行
target.publicMethod(false);
// 一回呼び出されたことの確認
assertThat(callMethod1Counter.get(), is(1L));
// 呼び出されないことの確認
assertThat(callMethod2Counter.get(), is(0L));
}
|
privateメソッドの呼び出し確認を行う場合の注意点
ここまでメソッドの呼び出し確認を行う方法をお話ししてきましたが、privateメソッドの呼び出し確認を行う場合には一つ注意があります。
Expectations内でのprivateメソッドのモック化は、バージョン1.23で廃止されました。
そしてなぜかMockUpでのprivateのモック化も同様にできないようです。
当然ながら呼び出し確認も行うことができません。
しかし、バージョン1.45からMockUp内でprivateメソッドのモック化ができるようになっています。
そのため、privateメソッドの呼び出し確認を行う際は、バージョン1.22以前、もしくはバージョン1.45以降を利用する必要があります。