关于类:如何在Java Junit中测试异常

How to test exception in Java Junit

本问题已经有最佳答案,请猛点这里访问。

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

1
2
3
4
5
6
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");
}

测试:

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

谢谢你的帮助。


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

1
@Test(expected = IllegalArgumentException.class)

取下@Test(expected = IllegalArgumentException.class),您会看到测试失败。

编辑以答复您的评论:为什么我看不到"无效号码"信息?

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


你好像在问为什么

1
2
3
4
5
6
public void validateState(String number) {
    if (!number.matches(...))
        throw new IllegalArgumentException("Invalid number");

    System.out.println("Invalid number");
}

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

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

如果希望引发异常并打印消息,请这样编写:

1
2
3
4
5
6
public void validateState(String number) {
    if (!number.matches(...)) {
        System.out.println("Invalid number");
        throw new IllegalArgumentException("Invalid number");
    }
}


测试必须通过,您的逻辑是正确的。您的测试说它期望抛出一个异常,它确实会抛出。JUnit捕获异常,验证它并使测试通过。

1
expected = IllegalArgumentException.class

从您的@Test注释中删除这一行,它将开始抛出异常。