単体テストを実施する上で、面倒なものの1つが例外である。全てのコードを実行させたいとき、try~catch文があると、意図的に例外を発生させる必要がある。 比較的単純な例外であればよいが、IOExceptionやSQLExceptionなど外部の環境に起因するものはテストがしづらい。
そんな手間のかかる例外テストもJMockitでは簡単に実施することができる。モックの戻り値(result)を設定するときと同じように、resultにExceptionを設定するだけで例外がスローさせることができる。
サンプルプログラムで実装方法を説明する。
まずはテスト対象クラスを作成する。
ファイルを読み込むクラスである。ファイルの中身を1行ずつ読み込む。読み込みに失敗したときのためにIOExceptionをキャッチさせる。
package mockittest;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/** ファイル読み込みクラス */
public class FileRead {
/** ファイル読み込み */
public void readFile() throws IOException {
BufferedReader br = null;
try{
br = new BufferedReader(new InputStreamReader(
new FileInputStream("C:\\temp\\test.txt"), "MS932"));
// 1行ずつ読み込み
String line;
while((line = br.readLine()) != null){
System.out.println(line);
}
// 入出力例外発生
} catch(IOException e) {
throw e;
}finally{
if(br != null){
try{
br.close();
}catch(IOException e){
throw e;
}
}
}
}
}
次にテストクラス。BufferedReaderをモックして、readLineメソッドで例外を発生させる。 方法はとても簡単。resultに発生させたい例外クラスをセットするだけである(戻り値をセットするときの方法と同様)。
package mockittest;
import static org.junit.Assert.*;
import java.io.BufferedReader;
import java.io.IOException;
import org.junit.Test;
import mockit.Expectations;
import mockit.Mocked;
/** テストクラス */
public class MockitTest {
/** BufferedReaderのモック */
@Mocked
private BufferedReader br;
/** readFileのテストメソッド */
@Test
public void testReadFile() throws Exception {
new Expectations() {{
// モックするメソッドを呼ぶ
br.readLine();
// 発生させたい例外をresultにセットする
result = new IOException();
}};
try{
// readFileメソッド実行
FileRead sample = new FileRead();
sample.readFile();
// 入出力例外キャッチ
}catch(IOException e){
// テスト成功
return;
}
// テスト失敗
fail();
}
}