60 秒回答模板

写单元测试要围绕一个明确的最小行为单元,而不是把整个系统链路跑一遍。好的测试应遵循 Arrange、Act、Assert,输入可控、依赖可替换、断言具体、结果可重复。用例要覆盖正常路径、边界值、异常分支和历史回归;数据库、网络、时间、随机数、外部服务要用 fake、stub 或 mock 隔离。覆盖率只能说明代码被执行过,不能替代有效断言;测试还要快、稳定、命名清楚,并避免过度依赖内部实现。

考点 核心机制与工程取舍
难度 中高频面试题
回答目标 按定义、机制、场景讲清楚

深入解析

01

先确定测试边界

单元测试验证一个函数、类或领域服务的可观察行为。它不应该依赖真实数据库、真实网络和完整部署环境,否则更像集成测试,失败原因也难定位。

02

用例覆盖行为空间

除了正常输入,还要覆盖空值、边界值、重复调用、并发或顺序敏感场景、异常抛出和失败返回。回归 bug 要补测试,确保同类问题不会再次出现。

03

断言要具体

断言不应只判断“没有报错”或“结果不为空”,而要验证关键输出、状态变化和副作用。一个测试最好聚焦一个行为,多个不相关断言拆成多个测试更易读。

04

依赖要可控

时间、随机数、UUID、环境变量、数据库、缓存、网络和第三方服务都会让测试不稳定。应通过接口注入、fake 实现、固定时钟、临时目录和事务回滚保证可重复。

05

不要迷信覆盖率

覆盖率能发现未执行代码,但高覆盖率不代表质量高。关键是核心路径、边界和异常是否有断言,测试是否能在重构时保护公共契约,而不是锁死内部实现。

易错点

  • 只追求覆盖率数字,没有有效断言关键行为。
  • 单元测试依赖真实时间、网络、数据库或执行顺序,导致 CI 间歇失败。
  • 一个测试验证过多无关行为,失败后难定位原因。
  • 过度 mock 内部实现,让重构破坏测试但业务行为没有问题。

面试官追问

mock 越多越好吗?

不是。mock 外部依赖可以提高速度和稳定性,但过度 mock 内部实现会让测试脆弱,重构稍微改调用方式就失败。优先断言公共行为和契约。

覆盖率越高越好吗?

覆盖率是参考指标。没有断言的高覆盖率价值很低,低风险 getter/setter 追求 100% 也不划算。应优先覆盖核心业务、边界和历史 bug。

单元测试和集成测试怎么区分?

单元测试隔离外部依赖,验证最小行为单元;集成测试验证多个模块或真实依赖协作。两者都需要,但反馈速度、失败定位和维护成本不同。

如何让测试可重复?

固定时间和随机数,隔离数据,避免依赖执行顺序,清理全局状态,使用临时资源,禁止访问不稳定外部服务。测试在本地和 CI 应得到一致结果。