assertthrows是junit 5中用于精准断言指定异常的核心方法,它接收异常类(如illegalargumentexception.class)和executable lambda,返回异常实例以支持消息、原因、字段等深度校验,替代了junit 4中功能受限的@test(expected=)。

在 JUnit 5 中,assertThrows 是专门用于验证代码是否抛出指定异常的断言方法,它不仅能确认异常发生,还能获取异常实例进行进一步校验(如消息、原因、状态等),从而实现“精准断言”。
明确指定异常类型并捕获实例
最基础也最关键的一步:传入期望的异常类(如 IllegalArgumentException.class),并用 lambda 表达式包裹待测逻辑。方法会返回实际抛出的异常对象,供后续断言使用。
- 写法示例:
assertThrows(NullPointerException.class, () -> obj.doSomething()); - 注意:不能只写异常类名(如
NullPointerException),必须带.class - 如果实际抛出的是子类(如
RuntimeException的子类),且断言类型是其父类(如RuntimeException.class),也会通过 —— 这是合理的向上兼容,但若需严格匹配具体类型,就一定要写准确的类
对异常实例做深度校验
仅确认“抛了异常”不够,业务中常需验证异常消息是否符合预期、是否包含特定字段、或是否有正确的 cause。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 获取异常后,可直接调用
getMessage()或getCause():
Exception e = assertThrows(IllegalArgumentException.class, () -> parse("invalid"));
assertTrue(e.getMessage().contains("format")); - 也可结合
Assertions.assertThat()(来自 AssertJ)或 JUnit 自带的assertEquals:
assertEquals("age must be positive", e.getMessage()); - 检查嵌套异常:
assertNotNull(e.getCause());
assertTrue(e.getCause() instanceof IOException);
避免常见陷阱
几个容易导致测试误通过或失败的细节:
- lambda 内部不能有额外语句(如打印、赋值),否则可能掩盖异常或改变执行路径;确保只有被测方法调用
- 不要用 try-catch 包裹再手动 fail —— 这绕过了
assertThrows的机制,丢失了异常实例,也违背 JUnit 5 设计意图 - 如果被测方法本不该抛异常,却意外抛出了其他类型异常(比如
NullPointerException),assertThrows会直接失败并报错,这反而是好事 —— 它帮你暴露了隐藏缺陷
配合 @Test(expected = ...)?不用了
JUnit 4 的 @Test(expected = ...) 只能声明异常类型,无法获取实例、无法校验消息、也不支持多个断言。JUnit 5 明确推荐用 assertThrows 替代,更安全、更灵活、更易调试。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










