JUnit 预期异常测试:@Test(expected)

JUnit 提供以下设施 trac抛出异常,并检查代码是否抛出了预期的异常。
JUnit 4 提供了一种简单易懂的异常测试方法。您可以使用:
- 可选参数(预期) @Test 注解和
- 至 trac可以利用这些信息,“fail()”函数。
而 测试 如果出现异常,您需要确保您在可选参数中提供的异常类是正确的。 @Test 注解 这与该方法实际抛出的异常相同。这是因为你期望该方法抛出一个异常。 单元测试否则我们的 JUnit 测试将会失败。
示例:@Test(expected = IllegalArgumentException.class)
通过使用“expected”参数,您可以指定测试可能抛出的异常名称。在上面的示例中,您使用的是“非法参数异常“,如果开发者使用了不允许的参数,则该测试会抛出此异常。
使用 @Test(expected) 的示例
让我们通过创建一个异常测试实例来理解异常测试。 Java 类中有一个方法会抛出异常 例外你将在一个测试类中处理并测试它。请考虑 JUnitMessage.java 文件中有一个执行数学运算的方法。第 14 行的除法运算除以了零,因此该方法总是抛出“ArithmeticException”异常。请参见下文:
package guru99.junit; public class JUnitMessage{ private String message; public JUnitMessage(String message) { this.message = message; } public void printMessage(){ System.out.println(message); int divide=1/0; } public String printHiMessage(){ message="Hi!" + message; System.out.println(message); return message; } }
Code 说明:
- Code 线7: 创建具有字段初始化的参数化构造函数。
- Code 第 11-14 行: 创建一种用于数学运算的方法。
- Code 线18: 创建另一种方法来打印消息。
- Code 线20: 创建一个新字符串来打印消息。
- Code 线22: 打印第 20 行创建的新消息。
让我们为上述内容创建一个测试类。 Java 用于验证异常的类。
下面这个测试类用于对上述代码抛出的异常(此处为 ArithmeticException)进行单元测试。 Java 类:
Airthematic测试.java
下面的屏幕截图显示了编辑器中的同一测试,文件保存为 AirthematicTest1,第 13 行突出显示了预期参数:
package guru99.junit; import static org.junit.Assert.assertEquals; import org.junit.Test; public class AirthematicTest { public String message = "Saurabh"; JUnitMessage junitMessage = new JUnitMessage(message); @Test(expected = ArithmeticException.class) public void testJUnitMessage(){ System.out.println("Junit Message is printing "); junitMessage.printMessage(); } @Test public void testJUnitHiMessage(){ message="Hi!" + message; System.out.println("Junit Message is printing "); assertEquals(message, junitMessage.printHiMessage()); } }
Code 说明:
- Code 线13: 使用 `@Test` 注解创建测试。执行上述类的方法时,它会调用一个数学运算。这里预期会抛出 `ArithmeticException` 异常,因此将其作为参数添加到 `@Test` 中。
- Code 线17: 从调用 printMessage() JUnit消息.java。
- Code 第 21-22 行: 创建另一个测试方法来检查 Hi 消息,这次没有预期的参数。
该类包含两个测试方法,因此一次运行会执行这两个方法:一个是期望返回 ArithmeticException 的方法,另一个是断言返回的字符串的方法。
注意: 这个示例在原始资料中有三个不同的名称——清单文件中的类名为 AirthematicTest,编辑器截图中显示为 AirthematicTest1,而结果视图中则显示为 JunitTestExample。代码完全相同,只有文件名不同。
让我们执行一下并验证结果。 JUnit 下方视图报告了运行情况 Junit测试示例.java.
输出:
以下是输出结果,显示测试成功,没有失败。 trace 如下所示:
两种方法都通过了。第一种方法通过是因为它声明的 ArithmeticException 异常确实发生了,第二种方法通过是因为返回的字符串匹配。如果除法运算没有抛出异常, JUnit 第一种方法会失败,并显示消息“预期异常:java.lang.ArithmeticException”。
测试异常的三种方法 JUnit 4
预期参数是三个参数中最短的。 JUnit 有 4 种习语,但并非总是正确的。表格通过两个决定选择的问题对它们进行比较:你能确定信息的含义吗?你知道是哪句话说的吗?
| 途径 | 这条信息是否属实? | 固定投掷线? | 最适合 |
| @Test(expected = X.class) | 没有 | 不——方法中的任何一行都可能抛出异常。 | 简短的测试,只关注异常类型。 |
| 尝试/失败/捕获 | 是的,在 catch 块内部 | 是的——只有经过监控的通话才会被监听。 | 必须检查信息或原因的测试。 |
| @Rule ExpectedException | 是的,通过 expectMessage() | 没有 | 传统套件已经基于规则构建。 |
引言中提到的 fail() 惯用法如下所示。如果调用没有抛出异常,fail() 就会运行,测试会报告你编写的消息:
@Test public void testDivideByZero() { try { junitMessage.printMessage(); fail("Expected an ArithmeticException"); } catch (ArithmeticException e) { assertEquals("/ by zero", e.getMessage()); } }
ExpectedException 规则位于两者之间。它已被弃用。 JUnit 4.13 倾向于使用接下来描述的 assertThrows 方法,因此是新的。 JUnit 4项测试不应采用它。
如何测试异常 JUnit 5. 使用 assertThrows()
JUnit 5 完全移除了 @Test 的预期参数。Jupiter 提供 assertThrows()它接受异常类和一个包含待测代码的 lambda 表达式。它会返回捕获到的异常,以便之后可以断言异常消息、异常原因以及任何自定义字段。
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; public class AirthematicJupiterTest { JUnitMessage junitMessage = new JUnitMessage("Saurabh"); @Test public void testJUnitMessage() { ArithmeticException thrown = assertThrows( ArithmeticException.class, () -> junitMessage.printMessage()); assertEquals("/ by zero", thrown.getMessage()); } }
三个相关 断言 完善家庭成员:
- 断言抛出异常 接受异常类型或其任何子类。
- assertThrowsExactly 拒绝子类,因此只有指定的类型才能通过。
- assertDoesNotThrow 这表明预期结果恰恰相反,即该代码块能够干净利落地完成。
此 JUnit 此页面上的 4 代码仍在运行 JUnit 平台通过复古引擎运行,因此在项目迁移过程中,以上所有内容都不需要重写即可继续工作。
测试异常时常见的错误 JUnit
异常测试会以少数几种可识别的方式失败。每一行都列出了症状、原因和解决方法。
| 症状 | 原因 | 固定 |
| 预期异常:java.lang.ArithmeticException | 该方法已成功完成,未出现任何异常。 | 确认输入确实无效后,重新运行。 |
| 测试通过了,但抛出了错误的行。 | 预期参数会监视整个方法,包括设置过程。 | 将设置移出,或者切换到 assertThrows 调用一次。 |
| 编辑器中出现未处理的异常类型 | 抛出了一个已检查异常,但从未声明过该异常。 | 在测试方法签名中添加 throws 异常。 |
| 测试通过了你意料之外的子类 | assertThrows 接受指定类型的子类。 | 使用 assertThrowsExactly 可以实现严格的类型匹配。 |
| expected 不是有效属性 | 该测试是针对 Jupiter @Test 注解编译的。 | 导入 org.junit.Test JUnit 4,或者移至 assertThrows。 |
最后一行最容易让迁移过程中的人出错,因为两个注解都叫做 @Test,只有导入语句才能区分它们。Keeping 一种 JUnit 每版本 测试用例 这类方法避免了整个类型的问题。



