この記事では@Mock
と@Spy
の使い分け方について解説します。
テスト対象として以下のCalc2.java
とSubCalc2.java
を用意し、Calc2.java
をテストするためのテストコードCalcTest2.java
を書きました。
プロダクトコード
Calc2.java
では、SubCalc2.java
の各メソッドの戻り値を確認できるようにprint文を仕込んでいます。
Calc2.java
package products;
public class Calc2 {
private SubCalc2 subCalc2;
public Calc2(){
this.subCalc2 = new SubCalc2();
}
public int add(){
int x = this.subCalc2.getValA();
System.out.println("変数x:" + x);
int y = this.subCalc2.getValB();
System.out.println("変数y:" + y);
int z = this.subCalc2.getValC(x, y);
System.out.println("変数z:" + z);
return x + y + z;
}
}
SubCalc2.java
のgetValC(int x, int y)
は完成しているとみなします。
SubCalc2.java
package products;
public class SubCalc2 {
public int getValA(){
// まだ開発途中
return 1;
}
public int getValB(){
// まだ開発途中
return 1;
}
public int getValC(int x, int y){
// このメソッドは完成!
return x * y;
}
}
テストコード
SubCalc2.java
のgetValC(int x, int y)
は完成しているのでモック化しません。
モック化するのはgetValA()
とgetValB()
のみとします。
CalcTest2.java
package products;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
public class CalcTest2 {
@InjectMocks
private Calc2 calc2;
@Mock
private SubCalc2 subCalc2;
@Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
@Test
public void test01(){
// SubCalcクラスの「getValA」メソッドをモックし、実行された場合は3を返す。
Mockito.doReturn(3).when(subCalc2).getValA();
// SubCalcクラスの「getValB」メソッドをモックし、実行された場合は4を返す。
Mockito.doReturn(4).when(subCalc2).getValB();
// 実行して結果を受け取る
int actual = calc2.add();
// 期待値の設定
int expected = 19;
// 検証
assertEquals(expected,actual);
}
@Test
public void test02(){
// ここは空振りするけど、initMocksは実行される。
}
}
Junit実行結果
実行結果は以下のとおりです。
calc2.add()
はgetValA()
とgetValB()
とgetValC(int x, int y)
の合計を返却します。
ですので、3+4+12=19となるはずですが、以下の実行結果を見ると7が返ってきているので失敗です。
java.lang.AssertionError: expected:<19> but was:<7>
コンソール
コンソールを見てみると変数zの値が0です。
つまりgetValC(int x, int y)
がうまく動作していないことが判ります。
変数x:3
変数y:4
変数z:0
修正箇所
テストコードの中の@Mock
アノテーションを@Spy
アノテーションに置き換えます。
修正前
// 修正前
@Mock
private SubCalc2 subCalc2;
修正後
// 修正後(「import org.mockito.Spy;」も必要)
@Spy
private SubCalc2 subCalc2;
上記修正後、テストコードを再実行すれば無事グリーンになるはずです。コンソール上も以下のとおり、変数zの値が取得できています。
変数x:3
変数y:4
変数z:12
解説
@Mock
アノテーション
モック化していないメソッドが呼び出されたとき、処理が空振りします。
@Spy
アノテーション
モック化していないメソッドが呼び出されたとき、記述したとおりに実行されます。
@Spy
アノテーションと@Mock
アノテーションの違い
テストコードの中で、モック化していない処理をそのまま実行させたいときは@Spy
アノテーションを使うのが良いということです。
以上で記事の解説はお終い!
もっとJavaやSpringを勉強したい方にはUdemyがオススメ!同僚に差をつけよう!