受检异常强制测试显式覆盖异常路径:测试须用throws声明或try-catch断言;assertthrows成标准验证方式;mock需抛出对应受检异常;频繁使用常倒逼重构为返回值或运行时异常。

受检异常的强制捕获机制,会直接改变单元测试的编写方式和验证逻辑——它不是让测试变难,而是要求测试必须显式覆盖“异常路径”。
测试必须声明或处理受检异常
当被测方法声明抛出 IOException、SQLException 等受检异常时,调用它的测试方法也必须: • 用 throws 声明(JUnit 5 允许,但会掩盖失败原因) • 或在测试体内用 try-catch 捕获并断言异常类型与消息 • 否则编译不通过,测试根本跑不起来
assertThrows 成为标准验证手段
JUnit 5 的 Assertions.assertThrows() 是应对受检异常最自然的方式:
• 它能捕获并返回异常实例,支持链式断言(如 e.getMessage().contains("not found"))
• 避免空 catch 块或仅打印日志的无效处理
• 对比运行时异常,这里不是“可选验证”,而是“必须验证”的分支路径
Mock 行为需匹配异常契约
若被测方法依赖外部组件(如文件读取、HTTP 调用),而这些组件抛出受检异常,那么在测试中 mock 它们时:
• 必须让 mock 明确抛出对应受检异常(例如 Mockito 的 when(fileReader.read()).thenThrow(new IOException("disk full")))
• 不能只 mock 返回值,否则测试无法进入异常处理分支
• 否则覆盖率看似达标,实则漏测关键错误恢复逻辑
重构倾向更明显
频繁出现受检异常会导致测试代码冗长、重复。这常倒逼开发者重构:
• 将异常转换为返回值(如 Optional











