单元测试覆盖率不达标的核心是识别未覆盖的逻辑分支、边界条件和异常路径并针对性补全;需借助IDE或JaCoCo生成详细报告,聚焦未覆盖行,按路径反推输入场景,善用参数化测试,并覆盖null、equals、日志等关键非业务点。

单元测试覆盖率不达标,核心不是“凑数”,而是识别未覆盖的逻辑分支、边界条件和异常路径,有针对性地补全测试用例。
定位具体哪部分没覆盖
先别急着写新用例,用 IDE(如 IntelliJ)或构建工具(如 Maven + JaCoCo)生成详细覆盖率报告,聚焦到类、方法、甚至某一行。重点关注:
- if/else、switch 的某个分支:比如 else 块完全没执行过
- 循环体内部或边界(空集合、单元素、多元素)
- try-catch 中的 catch 块:特别是受检异常或自定义异常抛出路径
- 构造函数或私有辅助方法:可能被忽略,但实际参与了主逻辑
按逻辑路径反推测试场景
看到未覆盖的代码行,直接问:“什么输入能让程序走到这里?”例如:
- 方法里有一行 if (user.getAge() → 补一个 age = -1 的测试用例,验证异常是否正确抛出
- 有个 if (list != null && !list.isEmpty()) → 分别测 list = null、list = new ArrayList()、list = Arrays.asList("a")
- 计算折扣的方法中,if (amount > 1000) return amount * 0.9; → 至少补 amount = 1001 和 amount = 1000 两个用例对比结果
善用参数化测试减少重复
对同一方法多个输入输出组合,别写一堆相似的 @Test 方法。用 JUnit 5 的 @ParameterizedTest + @ValueSource 或 @CsvSource 更清晰高效:
立即学习“Java免费学习笔记(深入)”;
- 比如校验邮箱格式的方法,一次性覆盖合法邮箱、空字符串、含空格、无@符号等十几种情况
- 避免为每个 case 单独命名方法,也避免复制粘贴断言逻辑
- 失败时能直接看到是哪个参数组合出的问题,排查更快
别忽略“非业务”但关键的测试点
有些代码看似简单,却常被漏测:
- 空参、null 参数调用:尤其 public 方法,应明确文档或抛 NPE/IllegalArgumentException
- 对象 equals/hashCode/toString:如果重写了,必须测一致性、对称性、哈希分布等
- Builder 模式或构造器的非法状态:比如必填字段缺失时是否拒绝构建
- 日志、监控埋点是否触发:可用 LogCaptor 或 Mockito.verify 检查 logger 调用


















