Jest testing best practices for JavaScript and TypeScript applications, covering test structure, mocking, and assertion patterns.
Install
npx skills add https://github.com/mindrally/skills --skill jestSKILL.md
Jest Testing Best Practices
You are an expert in JavaScript, TypeScript, and Jest testing.
Core Principles
Test Structure
- Use descriptive test names that clearly explain expected behavior
- Organize tests using
describeblocks for logical grouping - Follow the Arrange-Act-Assert (AAA) pattern in each test
- Keep tests focused on a single behavior or outcome
Setup and Teardown
- Use
beforeEachandafterEachfor test isolation - Use
beforeAllandafterAllfor expensive setup that can be shared - Clean up any side effects in teardown hooks
Mocking
- Use
jest.mock()for module mocking - Use
jest.fn()for function mocks - Use
jest.spyOn()when you need to track calls but keep implementation - Clear mocks between tests with
jest.clearAllMocks() - Avoid over-mocking: test real behavior when feasible
Assertions
- Use the most specific matcher available
- Prefer
toEqualfor object comparison,toBefor primitives - Use
toMatchSnapshotsparingly and with meaningful names - Include negative test cases (what should NOT happen)
Async Testing
- Always return promises or use async/await in async tests
- Use
waitForfrom testing libraries for async assertions - Set appropriate timeouts for long-running tests
Coverage
- Aim for meaningful coverage, not just high percentages
- Test edge cases and error conditions
- Use
--coverageflag to track coverage metrics
Best Practices
- Keep tests DRY but readable (prefer clarity over brevity)
- Test behavior, not implementation details
- Make tests deterministic (no random data without seeding)
- Use factories or builders for test data creation
Example Patterns
describe('fetchUser', () => {
it('should return user data when API call succeeds', async () => {
const mockUser = { id: 1, name: 'John' };
jest.spyOn(api, 'get').mockResolvedValue(mockUser);
const result = await fetchUser(1);
expect(result).toEqual(mockUser);
expect(api.get).toHaveBeenCalledWith('/users/1');
});
it('should throw error when API call fails', async () => {
jest.spyOn(api, 'get').mockRejectedValue(new Error('Not found'));
await expect(fetchUser(999)).rejects.toThrow('Not found');
});
});
Related skills
tddmattpocock979KTest-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.diagnosing-bugsmattpocock678KDiagnosis loop for hard bugs and performance regressions. Use when the user says "diagnose"/"debug this", or reports something broken/throwing/failing/slow.migrate-to-shoehornmattpocock388KMigrate test files from `as` type assertions to @total-typescript/shoehorn. Use when user mentions shoehorn, wants to replace `as` in tests, or needs partial test data.systematic-debuggingobra275KUse when encountering any bug, test failure, or unexpected behavior, before proposing fixes