assertthrows是junit 5中用于验证预期异常的断言方法,语法为assertthrows(异常类.class, () -> {...}),返回异常对象以校验类型和消息,不支持直接抛受检异常需用try-catch包装。

在JUnit 5中,assertThrows 是专门用于验证代码是否抛出预期异常的断言方法,它比手动写 try-catch 更简洁、语义更清晰,还能自动校验异常类型和消息。
用 assertThrows 替代 try-catch 的基本写法
传统 try-catch 写法需要手动捕获异常、检查类型、再显式失败(如没抛异常就 fail),容易出错且冗长。而 assertThrows 一行就能完成:断言“执行某段代码时必须抛出指定类型异常”,否则测试失败。
- 语法:
assertThrows(异常类.class, 可执行代码) - 返回值是实际抛出的异常对象,可用于进一步校验(比如异常消息)
- 可执行代码需用 Lambda 表达式(
() -> {...})或方法引用
校验异常类型和消息
只确认抛了异常还不够,常需验证异常类型是否准确、消息是否符合预期。
- 验证类型:
assertThrows(NullPointerException.class, () -> obj.toString()) - 同时验证消息:
Exception e = assertThrows(IllegalArgumentException.class, () -> parseAge(-5));
assertEquals("age must be positive", e.getMessage());
注意 Lambda 中不能直接抛受检异常
如果被测方法声明抛出受检异常(如 IOException),Lambda 无法直接调用——因为函数式接口 Executable 的 execute() 方法不声明抛异常。
- 解决办法:在 Lambda 内用
try-catch包裹并重新抛出为运行时异常(推荐封装工具方法) - 示例:
assertThrows(IOException.class, () -> { try { readFile(); } catch (IOException e) { throw new RuntimeException(e); } }); - 更优雅的做法是自定义一个支持受检异常的断言工具,或使用第三方库(如 AssertJ 的
catchThrowable)
常见错误和避坑点
- 忘记加括号导致编译失败:
() -> method()不可写成() -> method - 误用
assertThrows验证“不抛异常”的场景——它只用于“必须抛”,不抛会失败;要验证“不抛”,直接调用即可 - 在 Lambda 中执行多行逻辑时,确保所有路径都可能触发异常,否则可能漏测
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











