skills/unit-test-hook-best-practices/SKILL.md
Complete guide for testing React hooks — renderHook, Documentation by Harness, installStore, fixtures, subscription patterns, lint/compiler traps, and pre-completion checklist. Read docs/testing/unit-test-hook-best-practices.md for the full reference.
npx skillsauth add bkinsey808/songshare-effect unit-test-hook-best-practicesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Requires: file-read, terminal (test runner). No network access needed.
Also load: unit-test-best-practices/SKILL.md
— hook tests must follow all conventions from the general skill (AAA pattern, named constants,
mocking order, toStrictEqual, lint rules) in addition to the hook-specific rules here.
Use this skill when:
use*.ts / use*.tsx hook.Execution workflow:
renderHook tests and a Harness component. A Harness is always required — even when renderHook covers all behavior (see "Documentation by Harness" in the full reference).Output requirements:
renderHook vs Harness tests.describe blocks for renderHook tests and Harness tests:
describe("useMyHook — Harness", ...) and describe("useMyHook — renderHook", ...).it block must have explicit // Arrange, // Act,
// Assert comments. For tests that only verify initial state, use // Arrange + Act on the
setup line and // Assert — no Act: verifying initial render state only. For multi-step tests,
label each step // Act — cycle 1, // Act — cycle 2, etc.vi.resetAllMocks() in shared setup helpers — any setup*() helper shared across tests
must call vi.resetAllMocks() as its first line to prevent mock call-count leakage.vi.mock("path") + vi.mocked(...) and static top-level imports for test doubles when possible; avoid dynamic import() in tests unless the behavior specifically requires runtime module resolution.useItemTags), its returned setters are vi.fn() stubs that don't update React state. Assert
on a module-level named spy instead of expecting DOM changes.no-negated-condition in JSX — write x === undefined ? "absent" : "present", not
x !== undefined ? "present" : "absent".npm run test:unit -- path/to/useMyHook.test.tsx
npx oxlint --config .oxlintrc.json --type-aware path/to/useMyHook.test.tsx
npm run test:unit
docs/ai/rules.md.react-best-practices.tools
Zustand state management patterns for this project — store creation, selectors, Immer middleware, async actions with loading states, devtools, persist, and testing. Use when authoring or editing Zustand stores (use*Store files) or components that subscribe to stores. Do NOT use for React component structure or TypeScript-only utilities.
testing
How to write, update, or split skill files in this repo. Use when creating a new SKILL.md, updating an existing one, or deciding whether to put content in a skill vs. docs/.
development
Vitest unit test authoring for this repo — setup, mocking, API handler testing, and common pitfalls for non-hook code. Use when the user asks to add, update, fix, or review unit tests for utilities, components, API handlers, or scripts. Do NOT use for React hook tests — load unit-test-hook-best-practices instead.
development
TypeScript conventions for this repo (no `any`, explicit return types, JSDoc, exactOptionalPropertyTypes, ambient types, import style). Use when authoring or editing any `.ts` or `.tsx` file, resolving TypeScript strictness errors, or fixing type-related lint failures. Do NOT use for React-specific typing patterns (see react-best-practices skill) or JSDoc-only changes (see code-comment-best-practices skill).