.claude/skills/jest-unit/SKILL.md
Jest unit testing patterns for this Next.js application. Covers test structure, mocking strategies, React component testing, hook testing, and coverage targets. Use this skill when writing unit tests for services, hooks, utilities, or components.
npx skillsauth add NextSpark-js/nextspark jest-unitInstall 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.
Patterns for writing effective unit tests with Jest and React Testing Library.
TEST FILE STRUCTURE:
core/tests/jest/
├── api/ # API route tests
├── hooks/ # React hooks tests
├── lib/ # Utility tests
├── components/ # Component tests
├── services/ # Service tests
├── __mocks__/ # Mock utilities
│ ├── db-mocks.ts
│ ├── better-auth.js
│ └── next-server.js
└── setup.ts # Global configuration
contents/themes/default/tests/jest/
└── ... # Theme-specific tests
contents/plugins/*/__tests__/
└── ... # Plugin-specific tests
*.test.ts - TypeScript unit tests
*.test.tsx - React component tests
import { describe, test, expect, beforeEach, afterEach, jest } from '@jest/globals'
import { functionToTest } from '@/core/lib/module'
describe('ModuleName', () => {
beforeEach(() => {
jest.clearAllMocks()
})
afterEach(() => {
jest.clearAllMocks()
jest.resetModules()
})
describe('Feature Group', () => {
test('should do expected behavior when condition met', () => {
// Arrange
const input = 'test-data'
// Act
const result = functionToTest(input)
// Assert
expect(result).toBe('expected-output')
})
})
})
// jest.config.ts
import type { Config } from 'jest'
export const baseConfig: Partial<Config> = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/$1',
'^@/core/(.*)$': '<rootDir>/core/$1',
'next/server': '<rootDir>/core/tests/jest/__mocks__/next-server.js',
},
setupFilesAfterEnv: ['<rootDir>/core/tests/setup.ts'],
testTimeout: 10000,
}
pnpm test # Run all core tests
pnpm test:theme # Run theme-specific tests
pnpm test:coverage # Generate coverage reports
pnpm test:watch # Watch mode
jest.mock('@/core/lib/db', () => ({
queryWithRLS: jest.fn(),
queryOneWithRLS: jest.fn(),
mutateWithRLS: jest.fn(),
}))
const mockQueryWithRLS = queryWithRLS as jest.MockedFunction<typeof queryWithRLS>
test('example', async () => {
mockQueryWithRLS.mockResolvedValue([{ id: '123' }])
// ...
})
jest.mock('next/navigation', () => ({
useRouter: () => ({ push: jest.fn(), replace: jest.fn() }),
usePathname: () => '/',
useSearchParams: () => new URLSearchParams(),
}))
jest.mock('next-intl', () => ({
useTranslations: () => (key: string) => key,
useLocale: () => 'en',
}))
→ See references/mocking-patterns.md for complete mocking strategies
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
test('form submission', async () => {
const user = userEvent.setup()
render(<MyForm />)
await user.type(screen.getByLabelText('Email'), '[email protected]')
await user.click(screen.getByRole('button', { name: /submit/i }))
expect(await screen.findByText('Success')).toBeInTheDocument()
})
→ See references/component-testing.md for complete patterns
import { renderHook, act } from '@testing-library/react'
test('hook state update', () => {
const { result } = renderHook(() => useCounter())
act(() => {
result.current.increment()
})
expect(result.current.count).toBe(1)
})
→ See references/service-hook-testing.md for complete patterns
| Category | Target | Notes | |----------|--------|-------| | Critical Paths | 90%+ | Auth, API, Validation | | Features | 80%+ | UI, Business Logic | | Utilities | 80%+ | Helpers, Services | | Components | 70%+ | UI Components |
// Equality
expect(result).toBe('expected')
expect(result).toEqual({ id: '123' })
// Truthiness
expect(result).toBeTruthy()
expect(result).toBeNull()
expect(result).toBeDefined()
// Collections
expect(array).toHaveLength(2)
expect(array).toContain('item')
expect(obj).toHaveProperty('key')
// DOM (Testing Library)
expect(element).toBeInTheDocument()
expect(element).toHaveClass('className')
expect(element).toBeVisible()
expect(element).toBeDisabled()
// Mocks
expect(mockFn).toHaveBeenCalled()
expect(mockFn).toHaveBeenCalledWith('arg')
expect(mockFn).toHaveBeenCalledTimes(1)
// ❌ NEVER: Test implementation details
expect(result.current._internalState).toBe('value')
// ✅ CORRECT: Test observable behavior
expect(result.current.displayValue).toBe('value')
// ❌ NEVER: Skip cleanup
// No afterEach → leaks between tests
// ✅ CORRECT: Always cleanup
afterEach(() => jest.clearAllMocks())
// ❌ NEVER: Async without await
fetchData().then(data => expect(data).toBeDefined())
// ✅ CORRECT: Properly await
const data = await fetchData()
expect(data).toBeDefined()
// ❌ NEVER: Use fireEvent for user actions
fireEvent.change(input, { target: { value: 'text' } })
// ✅ CORRECT: Use userEvent
await user.type(input, 'text')
Before finalizing unit tests:
references/mocking-patterns.md - Complete mocking strategiesreferences/component-testing.md - React component testing patternsreferences/service-hook-testing.md - Service and hook testing patternscypress-e2e - Integration/E2E testingcypress-api - API testing with Cypresszod-validation - Schema validation testingservice-layer - Service patterns to testdevelopment
Zod validation patterns for this Next.js application. Covers schema definition, API validation, form integration, error formatting, and type inference. Use this skill when implementing validation for APIs, forms, or entity schemas.
development
Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".
testing
Test coverage metrics and registry system for this Next.js application. Covers FEATURE_REGISTRY, FLOW_REGISTRY, TAGS_REGISTRY, and coverage metrics interpretation. Use this skill when evaluating test coverage, identifying gaps, or planning testing priorities.
development
TanStack Query (React Query) patterns for data fetching in this Next.js application. Covers useQuery, useMutation, optimistic updates, cache invalidation, and anti-patterns. Use this skill when implementing data fetching or state management with server data.