Jest 适合测试函数、服务层、React 组件和异步逻辑。Supertest 则专门用于测试 HTTP 接口。
Jest 断言
常用断言:
expect(value).toBe(5);
expect(obj).toEqual({ id: 1 });
expect(value).toBeTruthy();
expect(arr).toContain("x");
expect(fn).toThrow(/error/);浮点数不要直接用 toBe。
expect(0.1 + 0.2).toBeCloseTo(0.3);单元测试
业务函数:
export function applyDiscount(price: number, discount: number) {
if (discount < 0 || discount > 1) return price;
return price * (1 - discount);
}测试:
test("calculates discount", () => {
expect(applyDiscount(100, 0.2)).toBe(80);
});
test("returns original price for invalid discount", () => {
expect(applyDiscount(100, 1.5)).toBe(100);
});Mock 外部请求
Mock 的目的不是“假装测试通过”,而是隔离外部依赖,让测试只关注当前逻辑。
jest.mock("axios");
const mockedAxios = axios as jest.Mocked<typeof axios>;
mockedAxios.get.mockResolvedValueOnce({
data: { id: 1, name: "Jesse" },
});
await expect(getUser(1)).resolves.toEqual({ id: 1, name: "Jesse" });
expect(mockedAxios.get).toHaveBeenCalledWith("/users/1");常见 Mock 对象:
- 网络请求
- 数据库仓库
- 时间函数
- 随机数
- 第三方服务
异步测试
await expect(fetchUser()).resolves.toMatchObject({ id: 1 });
await expect(fetchUser()).rejects.toThrow();异步测试一定要 return 或 await Promise,否则测试可能提前结束。
Supertest 测 API
Supertest 可以不启动真实端口,直接测试 Express/Next/Nest 接口。
const res = await request(app)
.get("/user/1")
.query({ detail: "full" })
.set("Authorization", "Bearer test123");
expect(res.statusCode).toBe(200);
expect(res.body).toHaveProperty("id", "1");POST JSON:
await request(app)
.post("/login")
.send({ username: "jesse", password: "123456" })
.expect(200);API 测试重点不是只看状态码,还要断言响应结构、错误分支、权限和边界输入。