| license | Apache-2.0 |
| name | vitest-testing-patterns |
| description | Write tests using Vitest and React Testing Library. Use when creating unit tests, component tests, integration tests, or mocking dependencies. Activates for test file creation, mock patterns, coverage, and testing best practices. |
| allowed-tools | Read,Write,Edit,Bash(npm:*,npx:*) |
| category | Code Quality & Testing |
| tags | ["testing","code","automation","jest","react"] |
Vitest Testing Patterns
Write effective tests using Vitest and React Testing Library following project conventions.
Decision Points
If testing authentication flows:
- If API route: Mock
getSession() → test 401/200 responses
- If component with auth hook: Mock
useAuth → test loading/authenticated/unauthenticated states
- If utility function: Mock auth service → test token validation logic
If testing async operations:
- If API calls: Use
waitFor() for state changes, mock fetch/axios
- If user interactions: Use
userEvent.setup() + await user.click()
- If timers/debouncing: Use
vi.useFakeTimers() + vi.advanceTimersByTime()
If testing form interactions:
- If simple inputs: Use
getByRole('textbox') + userEvent.type()
- If complex forms: Use
getByLabelText() for accessibility
- If validation: Test both valid submission and error states
If testing error boundaries:
- If component errors: Mock dependency to throw → verify error UI
- If network errors: Mock fetch rejection → test error handling
- If validation errors: Submit invalid data → verify error messages
If choosing mock strategy:
- If external API: Mock at module level (
vi.mock('@/lib/api'))
- If database queries: Mock ORM methods with chained returns
- If React hooks: Mock hook module, return test data
- If utilities: Mock implementation, verify calls with correct args
Failure Modes
Mock Pollution: Tests affect each other due to shared mock state
- Detection: Random test failures when run together but pass individually
- Fix: Add
vi.clearAllMocks() in beforeEach() or afterEach()
Over-Mocking: Mocking too much implementation detail, tests become brittle
- Detection: Tests break on refactors that don't change behavior
- Fix: Mock at boundaries (API calls, external services), not internal functions
Async Race Conditions: Tests fail sporadically due to timing issues
- Detection: Intermittent failures with "element not found" or timeout errors
- Fix: Use
waitFor() or findBy* queries instead of getBy* for async content
Query Priority Violations: Using low-priority queries when accessible ones exist
- Detection: Tests use
getByTestId or querySelector for interactive elements
- Fix: Replace with
getByRole('button'), getByLabelText(), etc.
Mock Implementation Drift: Mocks don't match real API changes
- Detection: Tests pass but integration fails in production
- Fix: Create shared mock factories, update mocks when API changes
Worked Example
Testing a form component with validation and API submission:
vi.mock('@/hooks/useAuth', () => ({
useAuth: vi.fn().mockReturnValue({
user: { id: 'user-123' },
isLoading: false,
}),
}));
vi.mock('@/lib/api', () => ({
submitForm: vi.fn(),
}));
describe('ContactForm', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('handles successful form submission', async () => {
const mockSubmit = vi.mocked(submitForm);
mockSubmit.mockResolvedValue({ success: true });
const user = userEvent.setup();
render(<ContactForm />);
await user.type(screen.getByLabelText(/name/i), 'John Doe');
await user.(screen.(), );
user.(screen.(, { : }));
( {
(screen.()).();
});
(mockSubmit).({
: ,
: ,
});
});
(, () => {
user = userEvent.();
();
user.(screen.(, { : }));
(screen.()).();
(screen.()).();
(submitForm)..();
});
});
Novice misses: Testing only happy path, using getByTestId, not cleaning mocks
Expert catches: Error states, accessible queries, mock verification, async handling
Quality Gates
NOT-FOR Boundaries
❌ DO NOT use for:
- End-to-end testing → Use
playwright-testing skill instead
- Performance testing → Use
performance-testing skill instead
- API contract testing → Use
openapi-testing skill instead
- Visual regression testing → Use
visual-testing skill instead
- Load testing → Use dedicated load testing tools
✅ USE this skill for:
- Unit tests for utilities and pure functions
- Component tests with React Testing Library
- Integration tests within a single module
- Mock patterns for external dependencies
- Test setup and configuration