// 👎 Don't do thistest('component sets loading state',()=>{constwrapper=shallow(<UserProfile/>);expect(wrapper.state('isLoading')).toBe(true);});// 👍 Do this insteadtest('shows loading state to users',()=>{render(<UserProfile/>);expect(screen.getByText('Loading...')).toBeInTheDocument();});
2. Smart Ways to Test User Actions
// 👎 Testing implementation detailstest('updates email state',()=>{constwrapper=shallow(<SignupForm/>);wrapper.find('input').simulate('change');expect(wrapper.state('email')).toBe('test@email.com');});// 👍 Testing user behaviortest('lets user submit their email',()=>{consthandleSubmit=jest.fn();render(<SignupFormonSubmit={handleSubmit}/>);// Type like a real user woulduserEvent.type(screen.getByRole('textbox',{name:/email/i}),'test@email.com');// Click like a real user woulduserEvent.click(screen.getByRole('button',{name:/submit/i}));expect(handleSubmit).toHaveBeenCalledWith('test@email.com');});
3. Stop Mocking Everything
// 👎 Over-mockingjest.mock('./UserAvatar');jest.mock('./UserBio');jest.mock('./UserStats');// 👍 Only mock what's necessary (like APIs)constserver=setupMSW([rest.get('/api/user',(req,res,ctx)=>{returnres(ctx.json({name:'John'}))})]);
4. Testing Hooks? Keep It Simple
// 👎 Complex setupconstwrapper=mount(<Providerstore={store}><ThemeProvidertheme={theme}><HookComponent/></ThemeProvider></Provider>);// 👍 Just test the logicconst{result}=renderHook(()=>useCounter());act(()=>{result.current.increment();});expect(result.current.count).toBe(1);
5. Write Fewer, Better Tests (Meaningful tests)
// 👎 Testing every little thingtest('renders header');test('renders subheader');test('renders each list item');test('renders footer');// 👍 Test important flowstest('lets user complete checkout flow',async ()=>{render(<CheckoutFlow/>);awaituserEvent.type(screen.getByLabelText(/card/i),'4242...');awaituserEvent.click(screen.getByText(/pay/i));expect(screen.getByText(/thanks for your order/i)).toBeInTheDocument();});
// 👍 Handle common async patternstest('shows loading and then content',async ()=>{render(<UserProfile/>);// Check loading stateexpect(screen.getByText(/loading/i)).toBeInTheDocument();// Wait for dataawaitscreen.findByText('John Doe');// Loading should be goneexpect(screen.queryByText(/loading/i)).not.toBeInTheDocument();});
8. Test Error States
// 👍 Don't forget error handlingtest('handles API errors gracefully',async ()=>{server.use(rest.get('/api/user',(req,res,ctx)=>{returnres(ctx.status(500))}));render(<UserProfile/>);awaitscreen.findByText(/something went wrong/i);expect(screen.getByRole('button',{name:/try again/i})).toBeInTheDocument();});
🎯 Quick Checklist Before Pushing
✅ Tests pass
✅ Tests are meaningful
✅ Used realistic user interactions
✅ Focused on behavior intead of implementation
✅ Covered error states
✅ Used resilient selectors
✅ Mocked only what's necessary
💡 Remember
Tests should give you confidence to refactor
If tests break when you refactor (but the app works), your tests are wrong
Test behavior, not implementation
When in doubt, test like a user
Top comments (0)
Subscribe
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Top comments (0)