我创建了以下方法,用于验证罗马数字转换器。在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");
}
}