jest
1. 安装依赖
bash
npm install -D jest @types/jest ts-jest supertest @types/supertest cross-env
| 包 | 作用 |
|---|---|
jest |
测试框架:跑测试、组织用例、断言、mock |
@types/jest |
让 TS 识别 describe、it、expect 等全局 API |
ts-jest |
让 Jest 直接运行 .ts 文件,无需先编译成 JS |
supertest |
对 Express 发 HTTP 请求并检查响应,无需浏览器/Postman |
@types/supertest |
supertest 的 TS 类型 |
cross-env |
跨平台设置环境变量(Windows 也能写 NODE_ENV=test) |
缺了会怎样:
- 无 jest → 没有测试框架
- 无 ts-jest → Jest 跑不了
.ts - 无 @types/* → 写测试时 TS 报类型错误
- 无 supertest → 不方便测 HTTP 接口
- 无 cross-env → Windows 上环境变量写法可能失效
2. 运行 npm test 时发生了什么
npm test
→ cross-env 设置 NODE_ENV=test
→ node 启动 Jest(ESM 需 --experimental-vm-modules)
→ 读取 jest.config.cjs
→ 先执行 tests/setup.ts
→ 找到 tests/*.test.ts
→ ts-jest 编译 TypeScript
→ supertest 向 Express 发请求
→ expect 断言 → 输出 PASS / FAIL
3. 各文件职责
| 文件 | 职责 |
|---|---|
package.json → test |
一键启动测试的命令 |
jest.config.cjs |
告诉 Jest 跑哪些文件、怎么编译 TS、路径怎么映射 |
tests/setup.ts |
每个测试运行前的公共初始化 |
tests/*.test.ts |
具体测试用例 |
tsconfig.json |
TS 编译规则 + Jest 类型支持 |
index.ts |
被测的 Express 应用;测试时不 listen,只 export |
4. package.json --- test 命令
json
"test": "cross-env NODE_ENV=test node --experimental-vm-modules node_modules/jest/bin/jest.js"
| 片段 | 含义 |
|---|---|
cross-env NODE_ENV=test |
设为测试模式,index.ts 里据此跳过 app.listen() |
node --experimental-vm-modules |
项目 "type": "module"(ESM),Jest 需要此开关 |
jest/bin/jest.js |
Jest 入口 |
index.ts 相关逻辑:
ts
if (process.env.NODE_ENV !== "test") {
app.listen(PORT, ...); // 正常启动才监听端口
}
export default app; // 测试时导出 app 给 supertest 用
5. jest.config.cjs --- Jest 配置
用 .cjs 是因为项目是 ESM,避免和 "type": "module" 冲突。
| 配置 | 含义 |
|---|---|
preset: "ts-jest/presets/default-esm" |
ts-jest 的 ESM 预设 |
testEnvironment: "node" |
在 Node 环境跑(测后端 API) |
extensionsToTreatAsEsm: [".ts"] |
把 .ts 当 ESM 模块 |
moduleNameMapper |
路径映射:../index.ts 和 @/xxx 能被正确解析 |
transform + useESM: true |
用 ts-jest 编译 TS,按 ESM 处理 |
setupFiles: ["tests/setup.ts"] |
每个测试前先跑 setup |
testMatch: ["**/tests/**/*.test.ts"] |
只跑 tests 目录下 .test.ts 文件 |
6. tests/setup.ts --- 测试前准备
ts
import "dotenv/config"; // 加载 .env(数据库地址等)
process.env.NODE_ENV = "test"; // 确保测试模式
7. tests/health.test.ts --- 示例用例
ts
import request from "supertest";
import app from "../index.ts";
describe("Get /health", () => { // 一组相关测试
it("returns 200 and status ok", async () => { // 一个具体场景
const res = await request(app).get("/health");
expect(res.status).toBe(200);
expect(res.body).toEqual({ status: "ok", message: "API is running" });
});
});
| API | 作用 |
|---|---|
describe |
分组,把相关测试包在一起 |
it |
一个测试用例 |
request(app).get(...) |
supertest 模拟 HTTP 请求 |
expect(...).toBe(...) |
断言:不符合预期则 FAIL |
8. tsconfig.json --- 测试相关项
json
"types": ["node", "jest"] // 加载 Jest 全局类型,否则 describe/expect 报错
"baseUrl" + "paths" // 路径别名 @/* → src/*
"ignoreDeprecations": "6.0" // TS6 中 baseUrl 已弃用,加此项消除编译报错
IDE 若报 ignoreDeprecations 值无效:Cursor 内置 TS5 不认识 "6.0"。
Ctrl+Shift+P → TypeScript: Select TypeScript Version → Use Workspace Version 即可。
.vscode/settings.json 已配置 "typescript.tsdk": "node_modules/typescript/lib" 指向项目 TS 版本。
9. 依赖协作关系
npm test
├── cross-env → NODE_ENV=test
├── jest → 找测试、跑测试、输出结果
├── ts-jest → 编译 .ts(读 tsconfig.json)
├── @types/jest → describe/it/expect 类型
├── supertest → 对 app 发 HTTP 请求
└── @types/supertest → request() 类型