抛出IOE时,JUnit需要IOException,将测试标记为失败

时间:2013-02-02 18:13:49

标签: java junit tdd ioexception

我有一些不符合预期的测试方法。在这些场景中,我正在将日志消息写入文本文件。

这两种方法都是关闭文件的输出链接并尝试写入文件。显然这意味着我期望IOException也会反映在我的代码中。

这是我正在谈论的两种测试方法

@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"));
}

两种写消息的方法属于同一路由。 writeToChatLog调用addMessage,然后调用writeToLogFile方法。

最后一种方法定义为

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();
    }
}

手头的问题是即使抛出IO错误(两次这样:):

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)

并显示弹出消息(Couldn't write to logfile),我仍然得到一个断言错误(java.lang.AssertionError: Expected exception: java.io.IOException)。

JUnit是第4版。

为什么会这样?

2 个答案:

答案 0 :(得分:4)

writeToLogFile()不会抛出IOException。如果是,则必须声明为

protected void writeToLogFile(String message) throws IOException {

您明确捕获任何可能从writeToLogFile()中的说明抛出的IOException。捕获异常正是用于避免抛出异常。

不要捕获IOException,并在方法声明中声明IOException,测试将通过:

protected void writeToLogFile(String message) throws IOException {
    if (logging) {
        bWriter.write(message);
        bWriter.newLine();
        bWriter.flush();
    } else {
        throw new ForbiddenActionException("Logging is disabled");
    }
}

答案 1 :(得分:4)

你永远不会真正抛出IOException。在writeToLogFile内你抓住它,记录它,什么都不做。从你外面的世界来看,没有发生任何错误:

protected void writeToLogFile(String message) {
    try {
        //...
    } catch (IOException e) {
        //...
        e.printStackTrace();
    }
}

你看,即使抛出IOException,也会被压制。因此,它永远不会从writeToClosedConnection()方法中转义,因此JUnit无法看到它。它没有通过测试。一个快速的解决方案是传播异常,遗憾的是需要修改你的签名:

protected void writeToLogFile(String message) throws IOException {
    try {
        //...
    } catch (IOException e) {
        //...
        throw e;
    }
}