# 好的测试与糟糕的测试 ## 好的测试 **集成风格**:通过真实接口进行测试,而非模拟内部组件。 ```typescript // 好:测试可观察的行为 test("用户可以使用有效购物车完成结账", async () => { const cart = createCart(); cart.add(product); const result = await checkout(cart, paymentMethod); expect(result.status).toBe("confirmed"); }); ``` 特征: - 测试用户/调用者关心的行为 - 仅使用公开 API - 能够经受内部重构 - 描述「做什么」,而非「怎么做」 - 每个测试只有一个逻辑断言 ## 糟糕的测试 **实现细节测试**:与内部结构耦合。 ```typescript // 差:测试实现细节 test("结账时调用 paymentService.process", async () => { const mockPayment = jest.mock(paymentService); await checkout(cart, payment); expect(mockPayment.process).toHaveBeenCalledWith(cart.total); }); ``` 危险信号: - 模拟内部协作对象 - 测试私有方法 - 对调用次数/顺序进行断言 - 重构(未改变行为)时测试破裂 - 测试名称描述「怎么做」而非「做什么」 - 通过外部手段而非接口进行验证 ```typescript // 差:绕过接口进行验证 test("createUser 保存到数据库", async () => { await createUser({ name: "Alice" }); const row = await db.query("SELECT * FROM users WHERE name = ?", ["Alice"]); expect(row).toBeDefined(); }); // 好:通过接口进行验证 test("createUser 使用户可被检索到", async () => { const user = await createUser({ name: "Alice" }); const retrieved = await getUser(user.id); expect(retrieved.name).toBe("Alice"); }); ```