write-tests
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWrite Tests for Existing Code
为现有代码编写测试
Before Writing, Ask Yourself
编写前,请先自问
- Module type? Route handler, repository, plugin, utility, or service — each has a different mock strategy
- Blast radius? Does this module have side effects (DB writes, API calls) that need isolation?
- Nearest test file? Find the closest and match its structure exactly
*.test.ts
- 模块类型? 路由处理器、仓库、插件、工具类或服务——每种类型都有不同的Mock策略
- 影响范围? 该模块是否有需要隔离的副作用(如数据库写入、API调用)?
- 最近的测试文件? 找到最近的文件,并完全匹配其结构
*.test.ts
Mock Strategy by Module Type
按模块类型划分的Mock策略
| Module Type | Strategy |
|---|---|
| Route handler | Test app builder + session simulation + |
| Repository | Mock DB connection + counter-based |
| Framework plugin | Real framework instance + selective dependency mocks |
| Pure utility | No mocks — test inputs/outputs directly |
| Service w/ DI | Mock injected deps via forwarding pattern |
| 模块类型 | 策略 |
|---|---|
| 路由处理器 | 测试应用构建器 + 会话模拟 + |
| 仓库 | Mock数据库连接 + 基于计数器的 |
| 框架插件 | 真实框架实例 + 选择性依赖Mock |
| 纯工具类 | 无需Mock——直接测试输入/输出 |
| 依赖注入服务 | 通过转发模式Mock注入的依赖项 |
Mock Setup (mockReset: true)
Mock设置(mockReset: true)
If your test runner uses , most examples from the internet will silently fail.
mockReset: truetypescript
const { mockFn } = vi.hoisted(() => ({
mockFn: vi.fn(),
}));
vi.mock("./dependency", () => ({
dependency: (...args: unknown[]) => mockFn(...args),
}));
beforeEach(() => {
// MUST reconfigure here — mockReset clears return values between tests
mockFn.mockResolvedValue(defaultResult);
});For complex TDZ cases (multiple interdependent mocks), use the globalThis registry pattern.
如果你的测试运行器启用了,网上的大多数示例都会静默失败。
mockReset: truetypescript
const { mockFn } = vi.hoisted(() => ({
mockFn: vi.fn(),
}));
vi.mock("./dependency", () => ({
dependency: (...args: unknown[]) => mockFn(...args),
}));
beforeEach(() => {
// MUST reconfigure here — mockReset clears return values between tests
mockFn.mockResolvedValue(defaultResult);
});对于复杂的TDZ(暂时性死区)场景(多个相互依赖的Mock),请使用globalThis注册表模式。
NEVER
绝对禁止
- NEVER chain —
mockResolvedValueOnceclears the chain between tests. Use counter-basedmockResetinstead.mockImplementation - NEVER define mock variables at module scope then reference in factories — hoisting creates a temporal dead zone. Use
vi.mock()or globalThis.vi.hoisted() - NEVER for modules with side effects — use selective re-exports.
vi.importActual() - NEVER test implementation details (private state, internal call order) — test behavior through the public API.
- NEVER copy mock patterns from other projects — check YOUR test runner config first.
- NEVER modify source code — this skill writes tests only.
- 绝对不要链式调用——
mockResolvedValueOnce会在测试间清除调用链。请改用基于计数器的mockReset。mockImplementation - 绝对不要在模块作用域定义Mock变量,然后在工厂中引用——变量提升会导致暂时性死区。请使用
vi.mock()或globalThis。vi.hoisted() - 绝对不要对有副作用的模块使用——请使用选择性重导出。
vi.importActual() - 绝对不要测试实现细节(私有状态、内部调用顺序)——请通过公开API测试行为。
- 绝对不要照搬其他项目的Mock模式——请先检查你自己的测试运行器配置。
- 绝对不要修改源代码——本技能仅负责编写测试。
Metacognitive Rule
元认知规则
If >3 tests fail on first run: STOP. The root cause is almost certainly a mock wiring issue affecting all tests, not individual test logic errors. Re-examine the mock setup strategy holistically before fixing tests one by one.
如果首次运行时有超过3个测试失败:请停止。 根本原因几乎肯定是影响所有测试的Mock配置问题,而非单个测试逻辑错误。在逐个修复测试前,请先全面检查Mock设置策略。
Run
运行测试
bash
npx vitest run <test-file> --reporter=verbosebash
npx vitest run <test-file> --reporter=verboseArguments
参数
- : Path to the source file or module to cover
$ARGUMENTS- Example:
/write-tests src/routes/admin/settings.ts - If empty, ask the user which file needs test coverage
- Example:
- : 需要覆盖测试的源文件或模块路径
$ARGUMENTS- 示例:
/write-tests src/routes/admin/settings.ts - 如果留空,请询问用户需要测试哪个文件
- 示例: