如何在 Java Junit 中测试异常 [重复]

Posted

技术标签:

【中文标题】如何在 Java Junit 中测试异常 [重复]【英文标题】:How to test exception in Java Junit [duplicate] 【发布时间】:2016-12-07 16:59:37 【问题描述】:

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

public void validateState(String number)
    if(!number.matches("^M0,4(CM|CD|D?C0,3)(XC|XL|L?X0,3)(IX|IV|V?I0,3)$"))
        throw new IllegalArgumentException("Invalid number");

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

测试:

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

感谢您的帮助。

【问题讨论】:

使用调试器找出来 它可能在你的正则表达式中,检查你正则表达式的有效性 小建议,一个字符串变量名“number”可能会导致潜在的混淆。 测试按预期运行:如果抛出异常,则测试通过。 demo 【参考方案1】:

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

@Test(expected = IllegalArgumentException.class)

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


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

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

【讨论】:

我没有看到“无效号码”消息是否正常? @user1526278 你怎么能看到在抛出异常并终止执行的语句之后写的东西?你那里的系统输出应该是相当“有效的数字” @user1526278 这取决于你如何运行测试。如果您使用的是 eclipse,您应该通过单击 junit 选项卡中测试附近的绿色进度条看到“无效数字”。当然,显示的文本将是异常消息和堆栈跟踪,而不是抛出异常后的 System.out.println。 @user1526278 另外,不要忘记使用大括号。在这种情况下,您的打印语句是 if 语句之外的。如果它在里面,你甚至无法编译它。 您应该在两条指令周围添加大括号并颠倒两条指令的顺序才能看到消息: System.out.println("Invalid number"); throw new IllegalArgumentException("Invalid number"); 【参考方案2】:

你似乎在问为什么

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

【讨论】:

【参考方案3】:

测试必须通过,你的逻辑是正确的。您的测试表明它期望抛出异常,并且确实如此。 Junit 捕获异常,对其进行验证并让测试通过。

expected = IllegalArgumentException.class 

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

【讨论】:

如果我删除 @Test(expected = IllegalArgumentException.class) 测试在其他测试用例上运行,编译器会跳转到我感兴趣的地方。 不,不要删除整个注释,如果你想看到错误,只需“expected = IllegalArgumentException.class”! 但我的测试代码是否正确? @Test(expected = IllegalArgumentException.class) public void test15() throws Exception new RomanNumber("").validateState("MMMMM"); @Adelin:当然。但我的疑问是为什么我看不到 IllegalArgumentException 发送的消息?只有这一个。测试代码有错误?

以上是关于如何在 Java Junit 中测试异常 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

JUnit 测试异常 [重复]

java Junit 测试中异常处理

来自 junit 测试的“分叉 Java VM 异常退出”错误

来自 junit 测试的“分叉 Java VM 异常退出”错误

junit测试中的Java.lang.nullpointerexception [重复]

在不同的 JUnit 测试中管理检查的异常