L.Leverage Learn从第一行代码,到读懂真实后端查看项目源码

NestJS 后端开发 / 第 16 课

NestJS 配置、日志与测试

管理环境配置的加载与校验,用日志诊断问题,并通过单元、集成和端到端测试反馈失败。

◷ 预计 30 分钟 · 面向初学者

同一份后端代码会在开发、测试和生产环境运行,但数据库地址、端口和 JWT 密钥不能写死在源文件。环境变量提供部署时的配置输入,配置模块负责读取、转换和校验,再由 ConfigService 注入到服务中。启动早期发现缺少 JWT_SECRET,比运行数小时后登录才报错更容易定位。配置应在应用生命周期开始时加载;业务代码不要到处读取 process.env 并自行解析,否则默认值和错误检查会分散。

配置含敏感值,.env 适合本地开发,不应提交真实密钥。生产环境通常由部署平台注入秘密。测试可提供独立的测试配置和替身,避免连到真实数据库、队列或用户账号。数据库连接、端口和密钥都要按环境检查格式;缺少必需项时让启动失败,并说明变量名,不要把变量值写进错误信息。

日志用来说明某次操作走到哪里以及失败位置。可记录请求 ID、路由、耗时、提交编号和异常类别;密码、Authorization 标头、JWT、用户源码和数据库连接串不应写入普通日志。异常日志要帮助排查,不能把内部堆栈直接返给客户端。失败反馈要能区分:配置错误在启动时报出,校验错误对应请求输入,Service 错误说明领域限制,测试断言失败则显示预期值和实际值。

三个测试范围

单元测试隔离一个类或函数,mock 依赖,快速检查分支。例如:

it('题目不存在时抛出 404', async () => {
  problemRepo.findOne.mockResolvedValue(null);
  await expect(service.create(18, dto)).rejects.toThrow(NotFoundException);
});

若实际错误不是 NotFoundException,测试会失败并显示断言不匹配;单测通过只能说明这条隔离路径符合预期,不能证明数据库真的返回空结果。

集成测试组合 Service、Repository 或模块,通常针对测试数据库验证查询和事务。测试数据须使用专用库并在前后清理,不能连接生产数据。**端到端测试(e2e)**从 HTTP 入口发请求,覆盖管道、Guard、控制器、服务及响应状态。例如发送无效 DTO,应断言响应为 400 且 Service 没有执行;请求有效但未携带登录凭证时,应断言 401。这样测试能发现配置漏装、路由路径错误或中间层没有生效的问题。

测试失败要先读断言和调用栈:若期望 400 却得到 500,检查错误是否被转换或意外访问外部依赖;若请求 401 但得到 200,检查 Guard 是否挂载及测试是否真的省略凭证。mock 的调用断言不等于集成测试,也不等于真实线上服务运行。本课示例用于说明写法,没有在后端仓库执行测试,不能据此宣称源项目测试通过。

小练习

一个 Service 单测 mock Repository 返回空记录并通过了,能否说明真实 MySQL 查询正确?若 e2e 中缺少 token 却得到 200,优先检查哪里?

**答案:**不能,mock 没执行真实 SQL;要用隔离测试库做集成验证。缺少 token 仍得到 200,应检查路由的 Guard 注册和 e2e 测试是否确实未发送凭证。

固定版本源码

互动练习:隔离配置与单元测试依赖

一个服务用环境变量连接外部邮件网关。单元测试应不联网且结果稳定;哪种方式最合适?

选择一个答案

✓
这一课,你已经能……

配置应在启动时读取并校验,日志记录可诊断但不泄密的信息;测试按隔离范围验证函数、模块协作和真实 HTTP 路径。