0

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

这两种方法都是关于关闭文件的输出链接并尝试写入文件。显然,这意味着我希望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"));
}

两种写消息的方法都属于同一个路由。writeToChatLoginvokes 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),我仍然得到一个 assertionError ( java.lang.AssertionError: Expected exception: java.io.IOException)。

JUnit 是第 4 版。

为什么会这样?

4

2 回答 2

4

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

protected void writeToLogFile(String message) throws IOException {

您明确地捕获了任何 IOException 可能从writeToLogFile(). 捕获异常正是为了避免抛出异常。

不要捕获 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");
    }
}
于 2013-02-02T18:17:30.213 回答
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;
    }
}
于 2013-02-02T18:17:40.333 回答