// 👎 Don't do this
test('component sets loading state', () => {
const wrapper = shallow(<UserProfile />);
expect(wrapper.state('isLoading')).toBe(true);
});
// 👍 Do this instead
test('shows loading state to users', () => {
render(<UserProfile />);
expect(screen.getByText('Loading...')).toBeInTheDocument();
});
2. Smart Ways to Test User Actions
// 👎 Testing implementation details
test('updates email state', () => {
const wrapper = shallow(<SignupForm />);
wrapper.find('input').simulate('change');
expect(wrapper.state('email')).toBe('test@email.com');
});
// 👍 Testing user behavior
test('lets user submit their email', () => {
const handleSubmit = jest.fn();
render(<SignupForm onSubmit={handleSubmit} />);
// Type like a real user would
userEvent.type(
screen.getByRole('textbox', { name: /email/i }),
'test@email.com'
);
// Click like a real user would
userEvent.click(screen.getByRole('button', { name: /submit/i }));
expect(handleSubmit).toHaveBeenCalledWith('test@email.com');
});
// 👎 Complex setup
const wrapper = mount(
<Provider store={store}>
<ThemeProvider theme={theme}>
<HookComponent />
ThemeProvider>
Provider>
);
// 👍 Just test the logic
const { result } = renderHook(() => useCounter());
act(() => {
result.current.increment();
});
expect(result.current.count).toBe(1);
5. Write Fewer, Better Tests (Meaningful tests)
// 👎 Testing every little thing
test('renders header');
test('renders subheader');
test('renders each list item');
test('renders footer');
// 👍 Test important flows
test('lets user complete checkout flow', async () => {
render(<CheckoutFlow />);
await userEvent.type(screen.getByLabelText(/card/i), '4242...');
await userEvent.click(screen.getByText(/pay/i));
expect(screen.getByText(/thanks for your order/i)).toBeInTheDocument();
});
// 👍 Handle common async patterns
test('shows loading and then content', async () => {
render(<UserProfile />);
// Check loading state
expect(screen.getByText(/loading/i)).toBeInTheDocument();
// Wait for data
await screen.findByText('John Doe');
// Loading should be gone
expect(screen.queryByText(/loading/i)).not.toBeInTheDocument();
});