assertThrows是JUnit 5中验证指定异常的核心方法,它接收异常类和Lambda表达式,返回异常实例以支持消息、字段等深度校验,相比try-catch+fail更简洁安全。

在 JUnit 5 中,assertThrows 是专门用于验证代码是否按预期抛出指定异常的断言方法。它不仅能确认异常发生,还能捕获异常实例,便于进一步检查异常消息、状态等细节。
基本用法:验证是否抛出指定异常类型
最常见场景是确认某段逻辑触发了预期的异常(如 IllegalArgumentException、NullPointerException 等)。
语法结构:
assertThrows(异常类.class, 可执行代码)- 返回值是实际抛出的异常对象,可用于后续断言
示例:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
@Test
void whenNegativeAge_thenThrowIllegalArgumentException() {
Exception exception = assertThrows(IllegalArgumentException.class, () -> {
new Person(-5); // 构造函数中 throw new IllegalArgumentException("age must be positive")
});
}
```
进阶用法:同时校验异常类型和异常消息
仅检查类型不够严谨,通常还需确认异常消息是否符合预期。可对 assertThrows 返回的异常对象调用 getMessage() 并配合 assertEquals 或 assertTrue。
示例:
立即学习“Java免费学习笔记(深入)”;
```java@Test
void whenNegativeAge_thenThrowWithCorrectMessage() {
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> {
new Person(-5);
});
assertEquals("age must be positive", exception.getMessage());
}
```
注意点:避免常见错误
-
不要直接调用被测方法:写成
assertThrows(..., someMethod())是错的——这会先执行方法并抛出异常,导致测试中断,无法进入断言逻辑;必须传入 Lambda 表达式或方法引用(即“延迟执行”) -
异常类型要精确匹配:若方法抛出的是子类异常(如
MyCustomException extends RuntimeException),而断言用了父类(如RuntimeException),虽然能通过,但降低了测试准确性;建议断言最具体的异常类型 - 不捕获异常时别忽略返回值:如果只关心是否抛异常,可忽略返回值;但一旦需要验证消息或字段,必须接收并使用返回的异常对象
替代方案对比:为什么不用 try-catch + fail?
老式写法(JUnit 4 常见):
```java@Test
void whenNegativeAge_thenThrow() {
try {
new Person(-5);
fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// success
}
}
```
问题:冗长、易出错(比如忘记 fail())、无法自然获取异常对象。而 assertThrows 更简洁、语义清晰、集成度高,是 JUnit 5 推荐的标准方式。

















