Jest React Testing
A comprehensive skill for testing React applications using Jest and React Testing Library. This skill covers everything from basic component testing to advanced patterns including mocking, async testing, custom hooks testing, and integration testing strategies.
When to Use This Skill
Use this skill when:
- Testing React components with Jest and React Testing Library
- Setting up Jest configuration for React projects
- Writing unit tests for components, hooks, and utilities
- Testing user interactions and component behavior
- Mocking modules, functions, API calls, and external dependencies
- Testing asynchronous operations (API calls, timers, promises)
- Testing custom React hooks
- Writing integration tests for complex component trees
- Debugging failing tests or improving test coverage
- Following testing best practices and patterns
Core Concepts
Testing Philosophy
React Testing Library follows these guiding principles:
- Test User Behavior, Not Implementation: Write tests that resemble how users interact with your app
- Accessibility First: Use queries that promote accessible components (getByRole, getByLabelText)
- Avoid Testing Implementation Details: Don't test state, props, or internal methods directly
- Maintainable Tests: Tests should break when behavior changes, not when code refactors
- Confidence Over Coverage: Focus on tests that give confidence, not 100% coverage
Key Testing Concepts
- Queries: Methods to find elements (getBy, queryBy, findBy)
- User Events: Simulating user interactions (click, type, select)
- Async Testing: Testing components with asynchronous operations
- Mocking: Replacing dependencies with controlled test doubles
- Assertions: Verifying expected outcomes with matchers
Jest Configuration
Basic Jest Configuration
jest.config.js (JavaScript projects):
jest.config.js (TypeScript projects):
Setup Files
src/setupTests.js:
File Mocks
mocks/fileMock.js:
mocks/styleMock.js:
React Testing Library Queries
Query Types
React Testing Library provides three types of queries:
- getBy: Returns element or throws error (use for elements that should exist)
- queryBy: Returns element or null (use for elements that may not exist)
- findBy: Returns promise that resolves to element (use for async elements)
Query Priority
Recommended Query Order (accessibility-focused):
-
getByRole: Most accessible query
-
getByLabelText: For form fields with labels
-
getByPlaceholderText: For inputs with placeholders
-
getByText: For non-interactive elements with text
-
getByDisplayValue: For form elements with values
-
getByAltText: For images with alt text
-
getByTitle: For elements with title attribute
-
getByTestId: Last resort when other queries don't work
Query Variants
Component Testing Strategies
Basic Component Test
Testing User Interactions
Testing Conditional Rendering
Mocking Patterns
Mocking Modules
Automatic Mock:
Usage in test:
Mocking Functions
Mocking API Calls with MSW (Mock Service Worker)
Setup MSW:
Setup server:
Configure in setupTests.js:
Usage in tests:
Mocking Context
Mocking Child Components
Async Testing Patterns
Testing with waitFor
Testing with findBy Queries
Testing Promises
Testing with Fake Timers
Testing Custom Hooks
Basic Hook Testing
Testing Hooks with Props
Testing Hooks with Context
Testing Async Hooks
Integration Testing Patterns
Testing Component Integration
Testing with Router
Testing with Redux
Jest DOM Matchers
Common Matchers
Best Practices
Test Organization
-
Group Related Tests: Use describe blocks to organize tests
-
Use Descriptive Test Names: Test names should describe behavior
-
Follow AAA Pattern: Arrange, Act, Assert
Query Best Practices
- Prefer Accessible Queries: Use getByRole, getByLabelText
- Use Screen Queries: Import from screen instead of destructuring render
- Avoid getByTestId: Use it as last resort only
- Use Regular Expressions: More flexible than exact strings
Async Testing Best Practices
- Use findBy for Async: Prefer findBy over getBy + waitFor
- Set Proper Timeouts: Configure waitFor timeouts for slow operations
- Avoid act() Warnings: Use userEvent, waitFor, findBy appropriately
- Clean Up Timers: Use jest.useFakeTimers() and cleanup properly
Mocking Best Practices
- Mock at Right Level: Mock external dependencies, not internal logic
- Reset Mocks: Clear mocks between tests
- Use MSW for API: Prefer MSW over mocking axios/fetch directly
- Avoid Over-Mocking: Don't mock what you're testing
Coverage Best Practices
- Focus on Behavior: Test user-facing behavior, not implementation
- Don't Chase 100%: Focus on critical paths
- Test Error States: Include error handling tests
- Test Edge Cases: Include boundary conditions
Common Testing Patterns
Testing Lists and Iterations
Testing Accessibility
Testing Error Boundaries
Testing Portals
Troubleshooting
Common Issues
Issue: "Unable to find element"
- Solution: Use screen.debug() to see DOM, check query type, wait for async updates
Issue: "Act warnings"
- Solution: Use userEvent instead of fireEvent, wrap state updates in act(), use waitFor/findBy
Issue: "Jest timeout"
- Solution: Increase timeout, check for infinite loops, ensure async operations complete
Issue: "Cannot read property of undefined"
- Solution: Check mocks are set up correctly, ensure components receive required props
Issue: "Multiple elements found"
- Solution: Make queries more specific, use getAllBy for multiple elements
Resources
Skill Version: 1.0.0
Last Updated: October 2025
Skill Category: Testing, React, Quality Assurance
Compatible With: Jest 29+, React Testing Library 13+, React 16.8+