I’ve got a few test methods that aren’t behaving as I expect them to be. In these scenarios, I’m writing logging messages to a text file.
Both methods are about closing the output link to the file and attempting to write to it. Obviously this means I expect an IOException which is also reflected in my code.
These are the two test methods I’m talking about
@Test(expected = IOException.class)
public void writeToClosedConnection() throws IOException {
LogHandler.getInstance().createNewChatlog("Jack");
LogHandler.getInstance().stopLogging(); // Closes the bufferedWriter
LogHandler.getInstance().writeToChatLog(new Message("Jim", "CAN'T WORK"));
}
@Test(expected = IOException.class)
public void closeStream() throws IOException {
log = new ChatLog(new GregorianCalendar(), "STANDARDTESTLOG", directory);
log.closeLogFile(); // Closes the bufferedWriter
log.addMessage(new Message("Jim", "CAN'T WORK"));
}
Both methods to write messages belong in the same route. writeToChatLog invokes addMessage, which will in turn call on the writeToLogFile method.
This last method is defined as
protected void writeToLogFile(String message) {
try {
if (logging) {
bWriter.write(message);
bWriter.newLine();
bWriter.flush();
} else {
throw new ForbiddenActionException("Logging is disabled");
}
} catch (IOException e) {
OutputUtil.showErrorMessage("Couldn't write to logfile", "IO error");
e.printStackTrace();
}
}
The issue at hand is that even though IO errors are thrown (twice this:)
java.io.IOException: Stream closed
at java.io.BufferedWriter.ensureOpen(Unknown Source)
at java.io.BufferedWriter.write(Unknown Source)
at java.io.Writer.write(Unknown Source)
at io.Log.writeToLogFile(Log.java:41)
at io.ChatLog.addMessage(ChatLog.java:16)
at tests.ChatLogTest.closeStream(ChatLogTest.java:76)
and the popup message (Couldn't write to logfile) is shown, I still get an assertionError (java.lang.AssertionError: Expected exception: java.io.IOException).
JUnit is version 4.
Why is this happening?
You never really throw
IOException. InsidewriteToLogFileyou catch it, log it and do nothing else. From you outside world perspective nothing wrong happened:You see, even if
IOExceptionwas thrown, it’s suppressed. Thus it never escapes out ofwriteToClosedConnection()method so JUnit can’t see it. And it fails the test. A quick solution would be to propagate the exception, which unfortunately requires modifying your signature: