name: write-vitest-test description: Write a Vitest test for this repo — API wrapper test with axios-mock-adapter or a component test with QueryClient + NextIntl providers. Use after adding a new API wrapper, hook, or component.
Write a Vitest Test
Reference
- API wrapper test pattern:
lib/api/__tests__/auth.test.ts - Component test wrapper:
components/auth/__tests__/ - Template:
reference/test-template.tsx.txt
Procedure
A. API wrapper test (lib/api/<domain>.ts)
- Create
lib/api/__tests__/<domain>.test.ts. - Use
new MockAdapter(apiClient)(imported from@/lib/api/client). beforeEach: instantiateMockAdapter.afterEach:mock.restore().- For each exported fn:
- Happy path:
mock.onMETHOD("/path").reply(200, response). Assert URL + body viaexpect(mock.history.METHOD[0].url).toBe(...). - Error path:
mock.onMETHOD("/path").reply(400, { ... }). Assert rejection shape.
- Happy path:
B. Hook test (hooks/use<Domain>.ts)
- Create
hooks/__tests__/use<Domain>.test.tsx. - Build a
wrapperthat provides a freshQueryClient(new QueryClient({ defaultOptions: { queries: { retry: false } } })) per test. - Use
renderHook(() => useFoo(...), { wrapper })from@testing-library/react. await waitFor(() => expect(result.current.isSuccess).toBe(true))then assertresult.current.datashape.
C. Component test (components/<domain>/<Name>.tsx)
- Create
components/<domain>/__tests__/<Name>.test.tsx. - Build
renderWithProviders(ui)that wraps with:QueryClientProvider(freshQueryClientper test, retries off)NextIntlClientProviderwithlocale="en"andmessagesloaded from a minimal fixture ormessages/en.json
- Drive interaction with
userEvent(not rawfireEvent). - Query by accessible role first:
getByRole("button", { name: /save/i }),getByLabelText("Email"). Fall back to test-id only when there's no role.
After writing
Run npm test -- <test-pattern> and ensure it passes. Don't leave failing or skipped tests behind.
Anti-patterns
- Hitting a real backend
- Reusing one
QueryClientacross tests (caches leak) - Mocking
useTranslationsto return key paths — provide a realNextIntlClientProviderwith messages instead - Loose assertions (
expect(x).toBeDefined()) - Snapshot tests for non-trivial components