Jest Core Knowledge Deep Knowledge : Use with technology: for comprehensive documentation. When NOT to Use This Skill - E2E Testing - Use or for browser automation - Vite Projects - Use which is faster and Vite-native - Component Testing Alone - Combine with for React/Vue components - API Integration Tests - Use framework-specific skills (spring-boot-integration, etc.) Basic Test Mocking Matchers Snapshots Async Testing Config Production Readiness Test Organization Coverage Configuration CI Integration Performance Optimization Monitoring Metrics | Metric | Target | |--------|--------| | Line…

: '\u003crootDir>/src/$1' }\n};\n```\n\n## Production Readiness\n\n### Test Organization\n\n```typescript\n// Isolated tests with proper setup/teardown\ndescribe('OrderService', () => {\n let service: OrderService;\n let mockRepository: jest.Mocked\u003cOrderRepository>;\n\n beforeEach(() => {\n mockRepository = {\n findById: jest.fn(),\n save: jest.fn(),\n delete: jest.fn(),\n } as jest.Mocked\u003cOrderRepository>;\n\n service = new OrderService(mockRepository);\n });\n\n afterEach(() => {\n jest.clearAllMocks();\n });\n\n describe('processOrder', () => {\n it('should process valid order', async () => {\n // Arrange\n const order = createTestOrder({ status: 'pending' });\n mockRepository.findById.mockResolvedValue(order);\n mockRepository.save.mockResolvedValue({ ...order, status: 'processed' });\n\n // Act\n const result = await service.processOrder(order.id);\n\n // Assert\n expect(result.status).toBe('processed');\n expect(mockRepository.save).toHaveBeenCalledWith(\n expect.objectContaining({ status: 'processed' })\n );\n });\n });\n});\n```\n\n### Coverage Configuration\n\n```javascript\n// jest.config.js\nmodule.exports = {\n collectCoverageFrom: [\n 'src/**/*.{ts,tsx}',\n '!src/**/*.d.ts',\n '!src/**/index.ts',\n '!src/**/*.stories.tsx',\n ],\n coverageThreshold: {\n global: {\n branches: 75,\n functions: 80,\n lines: 80,\n statements: 80,\n },\n },\n coverageReporters: ['text', 'lcov', 'html'],\n};\n```\n\n### CI Integration\n\n```yaml\n# GitHub Actions\n- name: Run tests\n run: npm test -- --ci --coverage --reporters=default --reporters=jest-junit\n env:\n JEST_JUNIT_OUTPUT_DIR: ./reports\n\n- name: Upload coverage\n uses: codecov/codecov-action@v3\n```\n\n```json\n// package.json\n{\n \"scripts\": {\n \"test\": \"jest\",\n \"test:ci\": \"jest --ci --coverage --maxWorkers=2\",\n \"test:watch\": \"jest --watch\"\n }\n}\n```\n\n### Performance Optimization\n\n```javascript\n// jest.config.js - Speed up tests\nmodule.exports = {\n // Run tests in parallel\n maxWorkers: '50%',\n\n // Cache transformations\n cacheDirectory: '\u003crootDir>/.jest-cache',\n\n // Only run affected tests\n onlyChanged: true,\n\n // Fail fast in CI\n bail: process.env.CI ? 1 : 0,\n};\n```\n\n### Monitoring Metrics\n\n| Metric | Target |\n|--------|--------|\n| Line coverage | > 80% |\n| Branch coverage | > 75% |\n| Test execution time | \u003c 120s |\n| Flaky test rate | 0% |\n\n### Checklist\n\n- [ ] Arrange-Act-Assert pattern\n- [ ] Isolated tests (no shared state)\n- [ ] Coverage thresholds enforced\n- [ ] CI/CD integration with reporting\n- [ ] jest.clearAllMocks() in afterEach\n- [ ] Meaningful test descriptions\n- [ ] Async tests properly awaited\n- [ ] Snapshot tests reviewed\n- [ ] Test data factories\n- [ ] Error scenarios covered\n\n## Anti-Patterns\n\n| Anti-Pattern | Why It's Bad | Solution |\n|--------------|--------------|----------|\n| Over-using snapshots | Tests pass without validation | Use snapshots sparingly, prefer explicit assertions |\n| Not reviewing snapshot changes | Bugs slip into snapshots | Always review snapshot diffs manually |\n| Testing implementation details | Brittle tests | Test user-facing behavior |\n| Shared mutable state | Flaky tests | Isolate setup with beforeEach |\n| Skipping error paths | Production failures | Test both success and error scenarios |\n| Large snapshot files | Hard to review | Break into smaller focused snapshots |\n| No mock cleanup | Tests affect each other | jest.clearAllMocks() in afterEach |\n\n## Quick Troubleshooting\n\n| Problem | Likely Cause | Solution |\n|---------|--------------|----------|\n| \"Cannot find module\" | Mock path incorrect | Ensure mock path matches import exactly |\n| Test timeout | Missing await | Add await to all async operations |\n| \"Received: serializes to same string\" | Object reference comparison | Use toEqual() not toBe() for objects |\n| Snapshot mismatch | Intentional code change | Review diff, update with -u flag if correct |\n| \"expect().resolves is not a function\" | Old Jest version | Update to Jest 27+ or use async/await |\n| Tests pass locally, fail in CI | Timezone/locale differences | Mock Date, use fixed timezones |\n\n## Reference Documentation\n- [Mocking](quick-ref/mocking.md)\n- [Snapshots](quick-ref/snapshots.md)\n---","attachment_filenames":["quick-ref/basics.md","quick-ref/mocking.md"],"attachments":[{"filename":"quick-ref/basics.md","content":"# Jest Basics Quick Reference\n\n> **Knowledge Base:** Read `knowledge/jest/basics.md` for complete documentation.\n\n## Test Structure\n\n```javascript\n// Basic test\ntest('adds 1 + 2 to equal 3', () => {\n expect(1 + 2).toBe(3);\n});\n\n// Describe blocks\ndescribe('Calculator', () => {\n describe('add', () => {\n test('adds positive numbers', () => {\n expect(add(1, 2)).toBe(3);\n });\n\n test('adds negative numbers', () => {\n expect(add(-1, -2)).toBe(-3);\n });\n });\n});\n\n// Skip and only\ntest.skip('skipped test', () => {});\ntest.only('only this runs', () => {});\ndescribe.skip('skipped suite', () => {});\n```\n\n## Common Matchers\n\n```javascript\n// Equality\nexpect(value).toBe(3); // Strict equality (===)\nexpect(obj).toEqual({ a: 1 }); // Deep equality\nexpect(obj).toStrictEqual({ a: 1 }); // Strict deep equality\n\n// Truthiness\nexpect(value).toBeTruthy();\nexpect(value).toBeFalsy();\nexpect(value).toBeNull();\nexpect(value).toBeUndefined();\nexpect(value).toBeDefined();\n\n// Numbers\nexpect(value).toBeGreaterThan(3);\nexpect(value).toBeGreaterThanOrEqual(3);\nexpect(value).toBeLessThan(5);\nexpect(value).toBeCloseTo(0.3, 5); // Float comparison\n\n// Strings\nexpect(str).toMatch(/pattern/);\nexpect(str).toContain('substring');\n\n// Arrays & Iterables\nexpect(array).toContain('item');\nexpect(array).toHaveLength(3);\nexpect(array).toContainEqual({ a: 1 });\n\n// Objects\nexpect(obj).toHaveProperty('key');\nexpect(obj).toHaveProperty('nested.key', 'value');\nexpect(obj).toMatchObject({ subset: true });\n\n// Negation\nexpect(value).not.toBe(3);\n```\n\n## Async Testing\n\n```javascript\n// Promises\ntest('async with promise', () => {\n return fetchData().then(data => {\n expect(data).toBe('data');\n });\n});\n\n// Async/await\ntest('async with await', async () => {\n const data = await fetchData();\n expect(data).toBe('data');\n});\n\n// Resolves/Rejects\ntest('resolves', () => {\n return expect(fetchData()).resolves.toBe('data');\n});\n\ntest('rejects', () => {\n return expect(fetchBadData()).rejects.toThrow('error');\n});\n\n// Callbacks (done)\ntest('callback', done => {\n fetchData(data => {\n expect(data).toBe('data');\n done();\n });\n});\n```\n\n## Setup & Teardown\n\n```javascript\n// Run before/after each test\nbeforeEach(() => {\n initializeDatabase();\n});\n\nafterEach(() => {\n clearDatabase();\n});\n\n// Run once per describe block\nbeforeAll(() => {\n return connectToDatabase();\n});\n\nafterAll(() => {\n return disconnectFromDatabase();\n});\n\n// Scoped to describe\ndescribe('with database', () => {\n beforeEach(() => { /* setup */ });\n afterEach(() => { /* cleanup */ });\n\n test('test 1', () => {});\n test('test 2', () => {});\n});\n```\n\n## Exceptions\n\n```javascript\n// Test for thrown errors\ntest('throws error', () => {\n expect(() => {\n throw new Error('wrong');\n }).toThrow();\n});\n\ntest('throws specific error', () => {\n expect(() => throwError()).toThrow('specific message');\n expect(() => throwError()).toThrow(/pattern/);\n expect(() => throwError()).toThrow(CustomError);\n});\n\n// Async errors\ntest('async throws', async () => {\n await expect(asyncThrow()).rejects.toThrow('error');\n});\n```\n\n## CLI Commands\n\n```bash\n# Run all tests\nnpx jest\n\n# Run specific file\nnpx jest path/to/test.js\n\n# Run tests matching pattern\nnpx jest --testNamePattern=\"pattern\"\n\n# Watch mode\nnpx jest --watch\nnpx jest --watchAll\n\n# Coverage\nnpx jest --coverage\n\n# Verbose output\nnpx jest --verbose\n\n# Update snapshots\nnpx jest --updateSnapshot\n```\n\n**Official docs:** https://jestjs.io/docs/getting-started\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":3520,"content_sha256":"9826a3b80829db22b1da9f7e747182afd7c1b1eb396c2284c29b9473cc90f88b"},{"filename":"quick-ref/mocking.md","content":"# Jest Mocking Quick Reference\n\n> **Knowledge Base:** Read `knowledge/jest/mocking.md` for complete documentation.\n\n## Mock Functions\n\n```javascript\n// Create mock function\nconst mockFn = jest.fn();\nconst mockWithReturn = jest.fn(() => 'default');\n\n// Call mock\nmockFn('arg1', 'arg2');\n\n// Assertions\nexpect(mockFn).toHaveBeenCalled();\nexpect(mockFn).toHaveBeenCalledTimes(1);\nexpect(mockFn).toHaveBeenCalledWith('arg1', 'arg2');\nexpect(mockFn).toHaveBeenLastCalledWith('arg1', 'arg2');\nexpect(mockFn).toHaveBeenNthCalledWith(1, 'arg1', 'arg2');\n\n// Return values\nmockFn.mockReturnValue('value');\nmockFn.mockReturnValueOnce('first').mockReturnValueOnce('second');\nmockFn.mockResolvedValue('async value');\nmockFn.mockRejectedValue(new Error('error'));\n\n// Implementation\nmockFn.mockImplementation((x) => x * 2);\nmockFn.mockImplementationOnce((x) => x * 3);\n\n// Reset\nmockFn.mockClear(); // Clear call history\nmockFn.mockReset(); // Clear + reset return values\nmockFn.mockRestore(); // Restore original (spyOn only)\n```\n\n## Spying on Methods\n\n```javascript\n// Spy on object method\nconst spy = jest.spyOn(object, 'method');\n\n// Spy with implementation\njest.spyOn(object, 'method').mockImplementation(() => 'mocked');\n\n// Spy on getter/setter\njest.spyOn(object, 'property', 'get').mockReturnValue('value');\njest.spyOn(object, 'property', 'set');\n\n// Restore original\nspy.mockRestore();\n\n// Example\nconst video = {\n play() { return true; }\n};\n\nconst spy = jest.spyOn(video, 'play');\nvideo.play();\n\nexpect(spy).toHaveBeenCalled();\nspy.mockRestore();\n```\n\n## Module Mocking\n\n```javascript\n// Mock entire module\njest.mock('./module');\n\n// Mock with factory\njest.mock('./module', () => ({\n fetchData: jest.fn(() => Promise.resolve('mocked')),\n processData: jest.fn()\n}));\n\n// Mock default export\njest.mock('./module', () => ({\n __esModule: true,\n default: jest.fn(() => 'mocked default'),\n namedExport: jest.fn()\n}));\n\n// Partial mock (keep some real implementations)\njest.mock('./module', () => ({\n ...jest.requireActual('./module'),\n specificFunction: jest.fn()\n}));\n\n// Mock in test file\nimport { fetchData } from './module';\njest.mock('./module');\n\ntest('uses mocked module', () => {\n fetchData.mockResolvedValue('data');\n // ...\n});\n```\n\n## Manual Mocks\n\n```javascript\n// __mocks__/axios.js\nexport default {\n get: jest.fn(() => Promise.resolve({ data: {} })),\n post: jest.fn(() => Promise.resolve({ data: {} }))\n};\n\n// Test file\nimport axios from 'axios';\njest.mock('axios');\n\ntest('fetches data', async () => {\n axios.get.mockResolvedValue({ data: { users: [] } });\n const result = await fetchUsers();\n expect(axios.get).toHaveBeenCalledWith('/api/users');\n});\n```\n\n## Timer Mocks\n\n```javascript\n// Enable fake timers\njest.useFakeTimers();\n\n// Advance timers\njest.advanceTimersByTime(1000); // 1 second\njest.runAllTimers(); // Run all pending\njest.runOnlyPendingTimers(); // Run only currently pending\n\n// Test with timers\ntest('calls callback after 1s', () => {\n const callback = jest.fn();\n setTimeout(callback, 1000);\n\n expect(callback).not.toHaveBeenCalled();\n\n jest.advanceTimersByTime(1000);\n\n expect(callback).toHaveBeenCalledTimes(1);\n});\n\n// Restore real timers\njest.useRealTimers();\n\n// Modern fake timers (recommended)\njest.useFakeTimers({ advanceTimers: true });\n```\n\n## Mocking Classes\n\n```javascript\n// Mock class\njest.mock('./SoundPlayer');\n\nimport SoundPlayer from './SoundPlayer';\n\ntest('mock class', () => {\n const player = new SoundPlayer();\n player.playSoundFile('song.mp3');\n\n expect(SoundPlayer).toHaveBeenCalledTimes(1);\n expect(player.playSoundFile).toHaveBeenCalledWith('song.mp3');\n});\n\n// Mock with implementation\njest.mock('./SoundPlayer', () => {\n return jest.fn().mockImplementation(() => ({\n playSoundFile: jest.fn()\n }));\n});\n```\n\n## Mocking Fetch/Axios\n\n```javascript\n// Mock fetch\nglobal.fetch = jest.fn();\n\nbeforeEach(() => {\n fetch.mockClear();\n});\n\ntest('fetches data', async () => {\n fetch.mockResolvedValue({\n ok: true,\n json: () => Promise.resolve({ data: 'result' })\n });\n\n const result = await fetchData();\n\n expect(fetch).toHaveBeenCalledWith('/api/data');\n expect(result).toEqual({ data: 'result' });\n});\n\n// Mock axios\nimport axios from 'axios';\njest.mock('axios');\n\ntest('posts data', async () => {\n axios.post.mockResolvedValue({ data: { id: 1 } });\n\n const result = await createUser({ name: 'John' });\n\n expect(axios.post).toHaveBeenCalledWith('/api/users', { name: 'John' });\n});\n```\n\n**Official docs:** https://jestjs.io/docs/mock-functions\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4562,"content_sha256":"823909ba282de4d97bd6c20a6e87a299e464f070e6373c90b938cedda279959c"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Jest Core Knowledge","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"Deep Knowledge","type":"text","marks":[{"type":"strong"}]},{"text":": Use ","type":"text"},{"text":"mcp__documentation__fetch_docs","type":"text","marks":[{"type":"code_inline"}]},{"text":" with technology: ","type":"text"},{"text":"jest","type":"text","marks":[{"type":"code_inline"}]},{"text":" for comprehensive documentation.","type":"text"}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When NOT to Use This Skill","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"E2E Testing","type":"text","marks":[{"type":"strong"}]},{"text":" - Use ","type":"text"},{"text":"playwright","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"cypress","type":"text","marks":[{"type":"code_inline"}]},{"text":" for browser automation","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Vite Projects","type":"text","marks":[{"type":"strong"}]},{"text":" - Use ","type":"text"},{"text":"vitest","type":"text","marks":[{"type":"code_inline"}]},{"text":" which is faster and Vite-native","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Component Testing Alone","type":"text","marks":[{"type":"strong"}]},{"text":" - Combine with ","type":"text"},{"text":"testing-library","type":"text","marks":[{"type":"code_inline"}]},{"text":" for React/Vue components","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"API Integration Tests","type":"text","marks":[{"type":"strong"}]},{"text":" - Use framework-specific skills (spring-boot-integration, etc.)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Basic Test","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"describe('UserService', () => {\n let service: UserService;\n\n beforeEach(() => {\n service = new UserService();\n });\n\n afterEach(() => {\n jest.clearAllMocks();\n });\n\n it('should create user', async () => {\n const user = await service.create({ name: 'John' });\n expect(user.name).toBe('John');\n });\n});","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Mocking","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"// Mock function\nconst mockFn = jest.fn();\nmockFn.mockReturnValue(42);\nmockFn.mockResolvedValue({ data: [] });\n\n// Mock module\njest.mock('./api', () => ({\n fetchUsers: jest.fn().mockResolvedValue([])\n}));\n\n// Spy\nconst spy = jest.spyOn(console, 'log');\nexpect(spy).toHaveBeenCalledWith('message');\n\n// Mock implementation\nmockFn.mockImplementation((x) => x * 2);","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Matchers","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"// Same as Vitest, Jest-compatible\nexpect(value).toBe(exact);\nexpect(value).toEqual(deepEqual);\nexpect(obj).toMatchObject({ name: 'John' });\nexpect(arr).toContainEqual({ id: 1 });","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Snapshots","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"it('should match snapshot', () => {\n const component = render(\u003cUserCard user={user} />);\n expect(component).toMatchSnapshot();\n});\n\nit('should match inline snapshot', () => {\n expect(formatDate(date)).toMatchInlineSnapshot(`\"2024-01-15\"`);\n});","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Async Testing","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"it('should resolve', async () => {\n await expect(fetchData()).resolves.toEqual({ data: [] });\n});\n\nit('should reject', async () => {\n await expect(fetchFail()).rejects.toThrow('Error');\n});","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Config","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"javascript"},"content":[{"text":"// jest.config.js\nmodule.exports = {\n testEnvironment: 'jsdom',\n setupFilesAfterEnv: ['\u003crootDir>/jest.setup.ts'],\n moduleNameMapper: { '^@/(.*)

Jest Core Knowledge Deep Knowledge : Use with technology: for comprehensive documentation. When NOT to Use This Skill - E2E Testing - Use or for browser automation - Vite Projects - Use which is faster and Vite-native - Component Testing Alone - Combine with for React/Vue components - API Integration Tests - Use framework-specific skills (spring-boot-integration, etc.) Basic Test Mocking Matchers Snapshots Async Testing Config Production Readiness Test Organization Coverage Configuration CI Integration Performance Optimization Monitoring Metrics | Metric | Target | |--------|--------| | Line…

: '\u003crootDir>/src/$1' }\n};","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Production Readiness","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Test Organization","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"typescript"},"content":[{"text":"// Isolated tests with proper setup/teardown\ndescribe('OrderService', () => {\n let service: OrderService;\n let mockRepository: jest.Mocked\u003cOrderRepository>;\n\n beforeEach(() => {\n mockRepository = {\n findById: jest.fn(),\n save: jest.fn(),\n delete: jest.fn(),\n } as jest.Mocked\u003cOrderRepository>;\n\n service = new OrderService(mockRepository);\n });\n\n afterEach(() => {\n jest.clearAllMocks();\n });\n\n describe('processOrder', () => {\n it('should process valid order', async () => {\n // Arrange\n const order = createTestOrder({ status: 'pending' });\n mockRepository.findById.mockResolvedValue(order);\n mockRepository.save.mockResolvedValue({ ...order, status: 'processed' });\n\n // Act\n const result = await service.processOrder(order.id);\n\n // Assert\n expect(result.status).toBe('processed');\n expect(mockRepository.save).toHaveBeenCalledWith(\n expect.objectContaining({ status: 'processed' })\n );\n });\n });\n});","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Coverage Configuration","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"javascript"},"content":[{"text":"// jest.config.js\nmodule.exports = {\n collectCoverageFrom: [\n 'src/**/*.{ts,tsx}',\n '!src/**/*.d.ts',\n '!src/**/index.ts',\n '!src/**/*.stories.tsx',\n ],\n coverageThreshold: {\n global: {\n branches: 75,\n functions: 80,\n lines: 80,\n statements: 80,\n },\n },\n coverageReporters: ['text', 'lcov', 'html'],\n};","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"CI Integration","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"yaml"},"content":[{"text":"# GitHub Actions\n- name: Run tests\n run: npm test -- --ci --coverage --reporters=default --reporters=jest-junit\n env:\n JEST_JUNIT_OUTPUT_DIR: ./reports\n\n- name: Upload coverage\n uses: codecov/codecov-action@v3","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"json"},"content":[{"text":"// package.json\n{\n \"scripts\": {\n \"test\": \"jest\",\n \"test:ci\": \"jest --ci --coverage --maxWorkers=2\",\n \"test:watch\": \"jest --watch\"\n }\n}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Performance Optimization","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"javascript"},"content":[{"text":"// jest.config.js - Speed up tests\nmodule.exports = {\n // Run tests in parallel\n maxWorkers: '50%',\n\n // Cache transformations\n cacheDirectory: '\u003crootDir>/.jest-cache',\n\n // Only run affected tests\n onlyChanged: true,\n\n // Fail fast in CI\n bail: process.env.CI ? 1 : 0,\n};","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Monitoring Metrics","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Metric","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Target","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Line coverage","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"> 80%","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Branch coverage","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"> 75%","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Test execution time","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\u003c 120s","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Flaky test rate","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"0%","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Checklist","type":"text"}]},{"type":"checkbox_list","attrs":{"id":null},"content":[{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Arrange-Act-Assert pattern","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Isolated tests (no shared state)","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Coverage thresholds enforced","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"CI/CD integration with reporting","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"jest.clearAllMocks() in afterEach","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Meaningful test descriptions","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Async tests properly awaited","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Snapshot tests reviewed","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Test data factories","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Error scenarios covered","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Anti-Patterns","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Anti-Pattern","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Why It's Bad","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Solution","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Over-using snapshots","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tests pass without validation","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use snapshots sparingly, prefer explicit assertions","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Not reviewing snapshot changes","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Bugs slip into snapshots","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Always review snapshot diffs manually","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Testing implementation details","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Brittle tests","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Test user-facing behavior","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Shared mutable state","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Flaky tests","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Isolate setup with beforeEach","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Skipping error paths","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Production failures","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Test both success and error scenarios","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Large snapshot files","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Hard to review","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Break into smaller focused snapshots","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"No mock cleanup","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tests affect each other","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"jest.clearAllMocks() in afterEach","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Quick Troubleshooting","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Problem","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Likely Cause","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Solution","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"Cannot find module\"","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Mock path incorrect","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Ensure mock path matches import exactly","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Test timeout","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Missing await","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Add await to all async operations","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"Received: serializes to same string\"","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Object reference comparison","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use toEqual() not toBe() for objects","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Snapshot mismatch","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Intentional code change","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Review diff, update with -u flag if correct","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\"expect().resolves is not a function\"","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Old Jest version","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Update to Jest 27+ or use async/await","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tests pass locally, fail in CI","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Timezone/locale differences","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Mock Date, use fixed timezones","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Reference Documentation","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Mocking","type":"text","marks":[{"type":"link","attrs":{"href":"quick-ref/mocking.md","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Snapshots","type":"text","marks":[{"type":"link","attrs":{"href":"quick-ref/snapshots.md","title":null}}]}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"jest","author":"@skillopedia","source":{"stars":19,"repo_name":"claude-dev-suite","origin_url":"https://github.com/claude-dev-suite/claude-dev-suite/blob/HEAD/skills/testing/jest/SKILL.md","repo_owner":"claude-dev-suite","body_sha256":"f2f75281c137a37868eca160b02574bc95c9e70660bae24a8b60131ccabc8c76","cluster_key":"cfe64295f19172ed20b3b82a0539531270e117ada3e3151988a492999861c108","clean_bundle":{"format":"clean-skill-bundle-v1","source":"claude-dev-suite/claude-dev-suite/skills/testing/jest/SKILL.md","attachments":[{"id":"b93f86c1-e994-5936-ba46-4b4d34a199e0","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/b93f86c1-e994-5936-ba46-4b4d34a199e0/attachment.md","path":"quick-ref/basics.md","size":3520,"sha256":"9826a3b80829db22b1da9f7e747182afd7c1b1eb396c2284c29b9473cc90f88b","contentType":"text/markdown; charset=utf-8"},{"id":"dc2759ea-649e-586f-88fe-699683310258","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/dc2759ea-649e-586f-88fe-699683310258/attachment.md","path":"quick-ref/mocking.md","size":4562,"sha256":"823909ba282de4d97bd6c20a6e87a299e464f070e6373c90b938cedda279959c","contentType":"text/markdown; charset=utf-8"}],"bundle_sha256":"a69e95cd246584f0af373db97de0259763b889bae272c0e8dc0e3ba0f41f3c2a","attachment_count":2,"text_attachments":2,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"skills/testing/jest/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"testing-qa","category_label":"Testing"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"testing-qa","import_tag":"clean-skills-v1","description":"Jest testing framework. Covers unit tests, mocking, and snapshots.\nUse for testing React and Node.js projects.\n\nUSE WHEN: user mentions \"jest\", \"jest test\", \"snapshot test\", asks about \"jest.fn\", \"jest.mock\", \"toMatchSnapshot\", \"React testing\"\n\nDO NOT USE FOR: E2E tests - use `playwright` or `cypress`; Vite projects - use `vitest` instead; React component testing alone - combine with `testing-library`\n","allowed-tools":"Read, Grep, Glob, Write, Edit"}},"renderedAt":1782988363251}

Jest Core Knowledge Deep Knowledge : Use with technology: for comprehensive documentation. When NOT to Use This Skill - E2E Testing - Use or for browser automation - Vite Projects - Use which is faster and Vite-native - Component Testing Alone - Combine with for React/Vue components - API Integration Tests - Use framework-specific skills (spring-boot-integration, etc.) Basic Test Mocking Matchers Snapshots Async Testing Config Production Readiness Test Organization Coverage Configuration CI Integration Performance Optimization Monitoring Metrics | Metric | Target | |--------|--------| | Line…