# When to Mock 仅在**系统边界**处进行 Mock: - 外部 API(支付、邮件等) - 数据库(偶尔使用——优先用测试数据库) - 时间/随机性 - 文件系统(偶尔使用) 不要 Mock: - 你自己的类/模块 - 内部协作组件 - 任何你能够控制的东西 ## 为可 Mock 性而设计 在系统边界处,设计易于 Mock 的接口: **1. 使用依赖注入** 将外部依赖传入,而非在内部创建: ```typescript // 易于 Mock function processPayment(order, paymentClient) { return paymentClient.charge(order.total); } // 难以 Mock function processPayment(order) { const client = new StripeClient(process.env.STRIPE_KEY); return client.charge(order.total); } ``` **2. 优先采用 SDK 风格的接口,而非通用 fetcher** 为每个外部操作创建特定函数,而非使用一个带条件逻辑的通用函数: ```typescript // 好:每个函数可独立 Mock const api = { getUser: (id) => fetch(`/users/${id}`), getOrders: (userId) => fetch(`/users/${userId}/orders`), createOrder: (data) => fetch('/orders', { method: 'POST', body: data }), }; // 差:Mock 需要在内部实现条件逻辑 const api = { fetch: (endpoint, options) => fetch(endpoint, options), }; ``` SDK 方式意味着: - 每个 Mock 返回一种特定的数据结构 - 测试设置中无需条件逻辑 - 更容易看出某个测试覆盖了哪些端点 - 每个端点都有类型安全