はじめに
単体テストでMockを使用しているので、振り返りも兼ねて簡単にまとめたいと思います。
Mockとは
簡単に説明すると、
**「テスト対象クラスから呼び出される、
部品(他のソース)の代わりになってくれるもの」。
例えば、計算結果を出力するテスト対象クラス、
実際に計算をしてくれるサブクラスがあったとする。
このサブクラスの代わりをしてくれるのがMock。ということ。
Mockまとめ
1.モックオブジェクトの生成
Sub sub = Mock(Sub.class);
Mockメソッドを使用してモックオブジェクトを生成
2.Mockito.when().thenReturn();
//aは部品の呼び出し処理
//bは呼び出された部品が返す値
Mockoito.when(sub.getAns()).thenReturn(b);
テスト対象ソースでSubクラスを呼び出しているが、
テストを通すにあたって、Subという部品が完成していない場合、
呼び出し部分でテストが落ちてしまい、最後まで通すことができない。
そのため上記処理を用いて、SubクラスのgetAnsメソッドが呼び出されたとき、
bという値を返すと指示しておけば、テストでその処理を通すことができる。
3.MockObjectManager.setReturnValueAt
//第1引数=クラス指定
//第2引数=メソッド名
//第3引数=呼び出し回数
//第4引数=戻り値の設定
MockObjectManager.setReturnValueAt(Sub.class, "getAns", 0, b);
MockObjectManager.setReturnValueAt(Sub.class, "getAns", 1, b);
2.のMockito.whenと共にこちらも使用。
注意点としては第3引数の呼び出し回数。
テスト対象ソースにて、同じ部品を複数回使用している場合は、
その回数に合わせて書く必要がある。
4.Mockito.any
//Mockito.any例
//↓int型の何がきてもbを返すよ~な設定
Mockito.when(sub.getAns(Mocito.anyInt(), Mockito.anyInt())).thenReturn(b);
テスト対象のMainクラスの中で、sub.getAnsを呼ぶときの引数を指定せずに、
int型であれば良しとするもの。
これは主にカバレッジをメインに見たい時に使用。
この他にもMockito.anyString()、Mockito.anyMap()、キャストして(クラス)Mockito.anyなどがある。
その他Mockを使うテストで使用していたもの
//Main=テスト対象ソース
Main main = new Main();
//Sub=他クラスの部品
Sub sub = new Sub();
//↓↓その他使用していたもの
//Mainクラスのフィールドで宣言されている変数subを指定
Field field = Main.getDeclaredField("sub");
//private変数へのアクセス制限を解除
field.setAccessible(true);
//private変数に値を設定
field.set(main, sub);
さいごに
Mock化について一連の流れで使用すると以下のようになる。
例1
Sub sub = Mock(Sub.class);
Field field = main.getDeclaredField("sub");
field.setAccessible(true);
field.set(main, sub);
//getAnsが引数2つの足し算のメソッドだった場合
Mockito.when(sub.getAns(1,1)).thenReturn(2);
例2
Sub sub = Mock(Sub.class);
Field field = main.getDeclaredField("sub");
field.setAccessible(true);
field.set(main, sub);
//getAnsの仮引数がDTO型だった場合
AnsDTO ansDto = new AnsDTO();
ansDto.setMath1(1);
ansDto.setMath2(1);
Mockito.when(sub.getAns(ansDto)).thenReturn(3);