JUnit5 的 @Test 方法无需声明 throws Exception,因框架自动捕获所有异常;验证异常应使用 assertThrows(),忽略异常则用 assertDoesNotThrow() 或显式 try-catch。

JUnit5 的 @Test 方法**不需要也不建议**在签名中使用 throws Exception 来简化测试代码——这反而会掩盖问题、降低可读性,且违背 JUnit5 的设计原则。
JUnit5 不强制检查异常声明
与 JUnit4 不同,JUnit5 的 @Test 方法签名无需声明受检异常(checked exception)。JUnit5 测试框架本身能捕获并报告任何未处理的异常(包括 Exception 及其子类),无论是否受检。
- 写
void testFoo() throws Exception是冗余的,编译器不会因异常未声明而报错 - 它无法提供额外保障,反而让方法签名显得“承诺抛异常”,但实际意图可能是验证异常是否发生
- 若真想验证异常,应使用
assertThrows()—— 这才是 JUnit5 推荐的明确、类型安全的方式
真正简化且推荐的做法:用 assertThrows 替代 throws 声明
当你要测试某段代码是否抛出特定异常时,直接在测试体内调用 Assertions.assertThrows(),既清晰又精准。
- ✅ 正确示例:
@Test
void testParseInvalidDate() {
IllegalArgumentException ex = assertThrows(
IllegalArgumentException.class,
() -> DateUtil.parse("invalid-date")
);
assertTrue(ex.getMessage().contains("unparseable"));
}
- ❌ 不推荐示例(看似省事,实则模糊):
@Test
void testParseInvalidDate() throws Exception { // 无意义声明,且无法校验异常类型/消息
DateUtil.parse("invalid-date"); // 异常会被框架捕获,但你没做任何断言
}
如果只是想“忽略”异常(不推荐)
极少数场景下,你仅需确认代码执行不崩溃(比如测试日志、副作用),但仍应显式处理,而非依赖 throws:
立即学习“Java免费学习笔记(深入)”;
- 用
assertDoesNotThrow()表达意图更明确 - 或直接 try-catch + fail(),避免静默失败
关于受检异常的特别说明
如果你调用的方法声明了受检异常(如 FileInputStream 构造),Java 编译器仍要求你处理它。此时优先选择:
- 在 lambda 或局部代码块中用 try-catch 包裹(配合
assertThrows) - 使用
Files等现代 NIO 工具替代老式 IO,减少受检异常 - 必要时才在测试方法签名加
throws,但仅限于让编译通过,不作为测试逻辑的一部分


















