如何在Java Junit中测试异常



我创建了以下方法,用于验证罗马数字转换器。在JUnit中,测试通过了,但程序没有抛出任何异常。我错在哪里了?

public void validateState(String number){
    if(!number.matches("^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$"))
        throw new IllegalArgumentException("Invalid number");
    System.out.println("Invalid number");
}

测试:

@Test(expected = IllegalArgumentException.class)
public void test15() throws Exception {
    new RomanNumber("").validateState("MMMMM");
}

谢谢你的帮助。

如果测试通过,则意味着IllegalArgumentException被抛出到方法中
否则,JUnit测试将失败,因为在这里您要断言抛出了IllegalArgumentException异常:

@Test(expected = IllegalArgumentException.class)

删除@Test(expected = IllegalArgumentException.class),您将看到测试失败。


编辑以回复您的评论:为什么我没有看到"无效号码"消息

如果任何调用方对象都没有捕捉到异常,那么您会在输出(终端)中看到带有stacktrace的异常。但正如我刚才在评论中所解释的,在您的情况下,您没有看到异常,因为它被JUnit(它是一个调用方对象)捕获,因为您在@Test注释中使用了预期的属性。当您运行方法时,JUnit运行程序会截获抛出的IllegalArgumentException,因为JUnit运行者知道它必须检查是否抛出了IllegalArgumentException
JVM只有在异常返回到调用堆栈顶部时才会在输出中写入异常(在这种情况下是错误流)(这意味着执行的代码中没有人捕捉到异常)

测试必须通过,您的逻辑是正确的。你的测试说它期望抛出一个异常,但它确实抛出了。Junit捕捉到异常,对其进行验证并通过测试

expected = IllegalArgumentException.class 

@Test注释中删除此行,它将开始引发异常。

您似乎在问为什么

public void validateState(String number) {
    if (!number.matches(...))
        throw new IllegalArgumentException("Invalid number");
    System.out.println("Invalid number");
}

不会引发异常并同时打印错误消息。

原因是当抛出异常时,它将传播跳过语句,直到在封闭的try ... catch中捕获到异常。在这种情况下,println调用将被跳过。这是正常的Java行为。。。

如果你想抛出异常并打印消息,可以这样写:

public void validateState(String number) {
    if (!number.matches(...)) {
        System.out.println("Invalid number");
        throw new IllegalArgumentException("Invalid number");
    }
}

相关内容

  • 没有找到相关文章

最新更新