write-tests

Use when adding or improving test coverage for existing source code without changing production behavior. Selects mock strategy by module type (route handler, repository, plugin, utility, service), handles mockReset:true environments, and prevents common vitest/jest mock wiring failures. Triggers on: write tests, add tests, test coverage, regression coverage, untested module, *.test.ts.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "write-tests" with this command: npx skills add acedergren/agentic-tools/acedergren-agentic-tools-write-tests

Write Tests for Existing Code

NEVER

  • NEVER chain mockResolvedValueOnce when mockReset: true — the chain clears between tests. Use counter-based mockImplementation instead.
  • NEVER define mock variables at module scope then reference them inside vi.mock() factories — hoisting creates a temporal dead zone. Use vi.hoisted() or globalThis registry.
  • NEVER vi.importActual() for modules with side effects — use selective re-exports instead.
  • NEVER test implementation details (private state, internal call order) — test observable behavior through the public API.
  • NEVER copy mock patterns from other projects — check YOUR test runner config first (mockReset, mockClear, restoreMocks).
  • NEVER modify source code — this skill writes tests only; production behavior is fixed.

Before Writing, Ask Yourself

  • Module type? Each has a different mock strategy (see table below).
  • Blast radius? Does this module have side effects (DB writes, API calls, filesystem) that need isolation?
  • Nearest test file? Find the closest *.test.ts and match its exact mock structure — don't invent a new pattern.

Mock Strategy by Module Type

Module TypeStrategy
Route handlerTest app builder + session simulation + app.inject()
RepositoryMock DB connection + counter-based execute
Framework pluginReal framework instance + selective dependency mocks
Pure utilityNo mocks — test inputs/outputs directly
Service w/ DIMock injected deps via forwarding pattern

Mock Setup (mockReset: true)

If your test runner uses mockReset: true, most examples from the internet will silently fail — return values clear between tests.

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:

vi.mock("./dep", () => {
  if (!(globalThis as any).__mocks) (globalThis as any).__mocks = {};
  const m = { dep: vi.fn() };
  (globalThis as any).__mocks.dep = m;
  return { dep: (...a: unknown[]) => m.dep(...a) };
});
// In tests: const mocks = (globalThis as any).__mocks;

Metacognitive Rule

If >3 tests fail on first run: STOP. Root cause is almost certainly a mock wiring issue affecting all tests — not individual test logic. Re-examine the mock setup holistically before fixing tests one by one.

Run

npx vitest run <test-file> --reporter=verbose

Arguments

  • $ARGUMENTS: Path to the source file or module to cover
    • Example: /write-tests src/routes/admin/settings.ts
    • If empty: ask the user which file needs test coverage

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

firecrawl

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

turborepo

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

humanizer

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

cloudflare-zero-trust

No summary provided by upstream source.

Repository SourceNeeds Review