Javaでファイルの出力を行うクラスを作成して、JUnitのテストを作成するときに、IOExceptionが発生するテストを実施する必要があります。IOExceptionを発生する方法を調べましたので、ここでそのやり方を説明します。
以下のファイル出力クラスを例として説明します。
public class FileIOExample {
public boolean writeFile() {
File file = new File("c://temp//a.txt");
try (OutputStream outstream = new FileOutputStream(file)) {
String data = "text to write\n";
outstream.write(data.getBytes()); // ①
return true;
} catch (IOException ex) {
ex.printStackTrace();
return false;
}
}
ファイルをオープンして出力する簡単なクラスですが、①の所でIOExceptionを発生させるテストケースを作成したい場合、以下のようにテストケースを記述します。
public class FileIOExampleTest {
@Test
public boolean writeFileTestForIOException() {
File file = new File("c://temp//a.txt");
try(RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw")){
// lock file
FileChannel channel = randomAccessFile.getChannel();
FileLock tryLock = channel.lock();
// テストの実行
FileIOExample fileIOExample = new FileIOExample();
boolean ret = fileIOExample.writeFile();
// 戻り値の確認
assertFalse(ret);
// release lock
tryLock.release();
}catch(IOException ex) {
ex.printStackTrace();
fail();
}
}
}
ここでのポイントは、ファイルをRWモードでオープンしてロックしても、new FileOutputStream(file)でファイルをオープンできるところです。その後のoutstream.write()の呼び出しで、ロックを検知したため、IOExceptionがスローされます。
また、テスト対象クラスでファイルを先にオープンして、テストコードでロックをかけることもできます。outstream.write()メソッドが実行される前に、ファイルをロックする必要があるため、Mockitoのモッククラスが利用します。モッククラスの戻り値を設定するテストコードにMockito.doAnswer()メソッドを利用します。doAnswer()メソッドで、戻り値を返す前に、ファイルにロックをかけるコードを記述できます。