Jest & React Testing Library Cheatsheet
Jest Core
Test Structure
describe('Component/Unit', () => {
beforeAll(() => {});
beforeEach(() => {});
afterEach(() => {});
afterAll(() => {});
it('should do something', () => {});
test('does something', () => {});
});
Matchers
// Common
expect(value).toBe(exact);
expect(value).toEqual(deepEqual);
expect(value).toBeTruthy();
expect(value).toBeFalsy();
expect(value).toBeNull();
expect(value).toBeUndefined();
expect(value).toBeDefined();
// Numbers
expect(value).toBeGreaterThan(3);
expect(value).toBeLessThan(5);
expect(value).toBeCloseTo(0.3);
// Strings
expect(str).toMatch(/regex/);
expect(str).toContain('substring');
expect(str).toHaveLength(6);
// Arrays/Objects
expect(arr).toContain(item);
expect(obj).toHaveProperty('key');
expect(arr).toHaveLength(n);
// Functions/Async
expect(fn).toThrow(error);
expect(promise).resolves.toBe(value);
expect(promise).rejects.toThrow(error);
Mocks
// Function Mocks
const mock = jest.fn();
mock.mockReturnValue(value);
mock.mockImplementation(() => value);
mock.mockResolvedValue(value);
mock.mockRejectedValue(error);
// Verifying Calls
expect(mock).toHaveBeenCalled();
expect(mock).toHaveBeenCalledWith(arg1, arg2);
expect(mock).toHaveBeenCalledTimes(n);
// Module Mocks
jest.mock('./module');
jest.spyOn(object, 'method');
React Testing Library
Rendering
import { render, screen } from '@testing-library/react';
// Basic Render
render(<Component />);
// With Providers
render(
<Provider>
<Component />
</Provider>
);
// With Router
render(
<MemoryRouter initialEntries={['/path']}>
<Component />
</MemoryRouter>
);
Queries
// Priority Order:
// 1. getByRole
// 2. getByLabelText
// 3. getByPlaceholderText
// 4. getByText
// 5. getByDisplayValue
// 6. getByAltText
// 7. getByTitle
// 8. getByTestId
// Variants:
// getBy: Expect element to be in DOM
// queryBy: Element might not be in DOM
// findBy: Async, element might appear in DOM
// Multiple elements:
// getAllBy, queryAllBy, findAllBy
// Examples
screen.getByRole('button', { name: /submit/i });
screen.getByLabelText('Username');
screen.getByPlaceholderText('Enter value');
screen.getByText(/hello/i);
screen.getByTestId('custom-id');
User Events
import userEvent from '@testing-library/user-event';
// Setup
const user = userEvent.setup();
// Events
await user.click(element);
await user.type(input, 'text');
await user.keyboard('{Enter}');
await user.selectOptions(select, ['option']);
await user.clear(input);
await user.tab();
Common Patterns
// Testing Form Submission
test('form submission', async () => {
const user = userEvent.setup();
const onSubmit = jest.fn();
render(<Form onSubmit={onSubmit} />);
await user.type(screen.getByLabelText('Email'), 'test@test.com');
await user.type(screen.getByLabelText('Password'), 'password');
await user.click(screen.getByRole('button', { name: /submit/i }));
expect(onSubmit).toHaveBeenCalled();
});
// Testing Async Actions
test('async data fetching', async () => {
render(<UserList />);
expect(screen.getByText('Loading...')).toBeInTheDocument();
await screen.findByRole('list');
expect(screen.getAllByRole('listitem')).toHaveLength(3);
});
// Testing Error States
test('error handling', async () => {
server.use(
rest.get('/api/users', (req, res, ctx) => {
return res(ctx.status(500));
})
);
render(<UserList />);
await screen.findByText('Error loading users');
});
Custom Hooks Testing
import { renderHook, act } from '@testing-library/react';
test('custom hook', () => {
const { result } = renderHook(() => useCustomHook());
act(() => {
result.current.update();
});
expect(result.current.value).toBe('updated');
});
Testing Best Practices
- Test behavior, not implementation
- Use accessible queries
- Avoid implementation details
- Test user interactions
- Test error scenarios
- Mock external dependencies
- Keep tests focused and simple
- Use meaningful test descriptions
- Follow Arrange-Act-Assert pattern
- Write maintainable tests