Trying to mock a constructor of FileWriter so that I can test the catch block. Here is my sample code:
public void write01() throws IOException {
BufferedWriter bufferedWriter = null;
try {
System.out.println("in try");
FileWriter fw = new FileWriter("c:\\t\\file.txt");
// bufferedWriter = new BufferedWriter(new FileWriter("c:\\t\\file.txt"));
bufferedWriter = new BufferedWriter(fw);
bufferedWriter.write("dfdf");
} catch (IOException e) {
e.printStackTrace();
} finally {
bufferedWriter.close();
}
}
}
Here are the tests I have tried:
public class WriteToFile01Test {
// does not work
@Test
@Disabled
public void testWrite01() throws IOException {
try (MockedStatic<FileWriter> fileWriterMock = mockStatic(FileWriter.class)) {
fileWriterMock.when(() -> new FileWriter("c:\\t\\file.txt"))
.thenThrow(new IOException());
WriteToFile01 writeToFile01 = new WriteToFile01();
writeToFile01.write01();
}
}
@Test
public void testWrite02() throws IOException {
try (MockedConstruction<FileWriter> fileWriterMock = mockConstruction(FileWriter.class, (mock, context) -> {
when(mock).thenThrow(new IOException());
// doThrow(new IOException()).when(mock);
// doThrow(new IOException()).when(mock).write(eq("dfdf"));
})) {
WriteToFile01 writeToFile01 = new WriteToFile01();
writeToFile01.write01();
}
}
@Test
public void testWrite02a() throws IOException {
try (MockedConstruction<FileWriter> fileWriterMock = mockConstruction(FileWriter.class, (mock, context) -> {
when(mock).thenThrow(new IOException()); // java.lang.NullPointerException: Cannot invoke "java.io.BufferedWriter.close()" because "bufferedWriter" is null
// doThrow(new IOException("error happened")).when(mock);
// doThrow(new IOException()).when(mock);
// doThrow(new IOException()).when(mock).write(eq("dfdf"));
})) {
WriteToFile01 writeToFile01 = new WriteToFile01();
writeToFile01.write01();
}
}
// works but file is created
@Test
public void testWrite03() throws IOException {
try (MockedConstruction<BufferedWriter> fileWriterMock = mockConstruction(BufferedWriter.class, (mock, context) -> {
doThrow(new IOException()).when(mock).write(eq("dfdf"));
})) {
WriteToFile01 writeToFile01 = new WriteToFile01();
writeToFile01.write01();
}
}
}
The goal is to mock FileWriter so that no file is created as tests may be run in Windows or *Nix. How to mock the constructor so the IOException is thrown?
jonrsharpe
123k31 gold badges278 silver badges489 bronze badges
asked Aug 9, 2025 at 20:49
Oxnard
4282 gold badges8 silver badges24 bronze badges
1 Answer 1
You can use mockConstructionWithAnswer to mock away a call to a constructor and replace it with an arbitrary behavior expressed as an Answer, including throwing an exception:
public void testWrite01() {
try (MockedConstruction<FileWriter> fileWriterMock =
mockConstructionWithAnswer(
FileWriter.class,
invocation -> {throw new IOException("mocked IOException");}
)) {
WriteToFile01 writeToFile01 = new WriteToFile01();
assertThrows(
IOException.class,
() -> writeToFile01.write01(),
"We mocked an IOException, so we expect it to be thrown");
}
}
answered Aug 9, 2025 at 21:19
Mureinik
316k54 gold badges404 silver badges406 bronze badges
Sign up to request clarification or add additional context in comments.
3 Comments
Oxnard
the code kind of worked. an IOException was thrown and a file was not created but in the WriteToFile01 class the catch block was not entered. Using the coverage tool in Eclipse the throw happened in the line bufferedWriter.write("dfdf");. would have thought the throw would occur in the line FileWriter fw = new FileWriter("c:\\t\\file.txt");
Mureinik
@Oxnard Mockito's instrumentation plays havoc with the stack trace. Try adding a simple call to
System.out.println after the call to new FileWriter, and it would look as though the exception came from there. Better yet, if you remove everything but the call to new FileWriter from write01, you'll still get an exception. In short - the exception come from the invoked constructor, even though the stacktrace is a bit off.Oxnard
did try putting in a
System.out.println after the call and did see the output. Additionally, placed a System.out.println in the catch block but did not see that output. Finally in the assertThrows in the Unit Test placed a NPE just to see what happens. It failed as one would expect. An IOException is being thrown just odd the catch block is not catching it while running the Unit Test. Thanks for taking a look at it.