Agent skill
jest-unit
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.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/other/jest-unit
SKILL.md
Jest Unit Testing Skill
Patterns for writing effective unit tests with Jest and React Testing Library.
Architecture Overview
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
When to Use This Skill
- Writing unit tests for services
- Testing React hooks
- Testing React components
- Mocking database operations
- Setting up test coverage
Test File Structure
Naming Conventions
*.test.ts - TypeScript unit tests
*.test.tsx - React component tests
Standard Test Structure
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 Configuration
// 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,
}
Test Scripts
pnpm test # Run all core tests
pnpm test:theme # Run theme-specific tests
pnpm test:coverage # Generate coverage reports
pnpm test:watch # Watch mode
Essential Mocking (Quick Reference)
Database (MANDATORY)
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' }])
// ...
})
Next.js Navigation
jest.mock('next/navigation', () => ({
useRouter: () => ({ push: jest.fn(), replace: jest.fn() }),
usePathname: () => '/',
useSearchParams: () => new URLSearchParams(),
}))
Translations
jest.mock('next-intl', () => ({
useTranslations: () => (key: string) => key,
useLocale: () => 'en',
}))
→ See references/mocking-patterns.md for complete mocking strategies
Quick Testing Patterns
Component Test
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
Hook Test
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
Coverage Targets
| Category | Target | Notes |
|---|---|---|
| Critical Paths | 90%+ | Auth, API, Validation |
| Features | 80%+ | UI, Business Logic |
| Utilities | 80%+ | Helpers, Services |
| Components | 70%+ | UI Components |
Common Assertions
// 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)
Anti-Patterns
// ❌ 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')
Checklist
Before finalizing unit tests:
- All database calls mocked (queryWithRLS, mutateWithRLS)
- External APIs mocked (fetch)
- Next.js functions mocked (useRouter, useSearchParams)
- afterEach cleanup with jest.clearAllMocks()
- Async tests properly awaited
- Test both success and error paths
- Edge cases covered (null, empty, invalid input)
- Coverage targets met (90%+ critical, 80%+ features)
- Test names are descriptive
References
references/mocking-patterns.md- Complete mocking strategiesreferences/component-testing.md- React component testing patternsreferences/service-hook-testing.md- Service and hook testing patterns
Related Skills
cypress-e2e- Integration/E2E testingcypress-api- API testing with Cypresszod-validation- Schema validation testingservice-layer- Service patterns to test
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?