Testing your React components might sound intimidating, but with Jest, itβs actually fun! π
In the era of AI, many people believe that Unit Testing is dead or no longer necessary. π«π€ But let me tell youβit's one of the most underrated skills in software development! π‘β¨
While most developers tend to skip it, thinking it's not essential, Unit Testing is actually a secret weapon π‘οΈ that can elevate your code quality and save countless hours of debugging. πβ±οΈ
In fact, I believe that learning Unit Testing is far more important than jumping on the bandwagon of the next shiny framework. ππ
Mastering this skill will not only make your codebase more reliable but also make you a better developer. π»β
In this blog, I'll dive into Jest for unit testing React components.Letβs get our hands dirty! πͺ
πΉ Why Jest?
Before we jump in, why should you even care about Jest?
Jest is a delightful JavaScript testing framework created by Facebook
. Itβs fast
, easy to set up
, and works seamlessly with React
.
Plus, it comes with built-in support for mocking
, assertions
, and code coverage
. π οΈ
Alright, enough chit-chat. Letβs code! πͺ
π¦ Setting Up Jest
- Create React App (already comes with Jest):
npx create-react-app my-app
cd my-app
npm test
Boom! Jest is running. π But this method is deprecated so we can use other module bundler like Vite, Webpack etc. and setup jest manually.
- Manual Setup:
npm install --save-dev jest @testing-library/react @testing-library/jest-dom
π§ Writing Your First Test
Letβs create a simple component and test it!
Counter.js
import React, { useState } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
return (
<div>
<h1 data-testid="count">{count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default Counter;
π Counter.test.js
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import Counter from './Counter';
test('renders initial count', () => {
render(<Counter />);
const countElement = screen.getByTestId('count');
expect(countElement).toHaveTextContent('0');
});
test('increments count on button click', () => {
render(<Counter />);
const buttonElement = screen.getByText('Increment');
fireEvent.click(buttonElement);
const countElement = screen.getByTestId('count');
expect(countElement).toHaveTextContent('1');
});
π Run Tests
npm run test
You should see green checkmarks! ππΉ
π Snapshot Testing
Want to make sure your UI doesnβt change unexpectedly? Use snapshots! πΈ
import React from 'react';
import { render } from '@testing-library/react';
import '@testing-library/jest-dom';
import Counter from './Counter';
test('matches snapshot', () => {
const { asFragment } = render(<Counter />);
expect(asFragment()).toMatchSnapshot();
});
Run the test, and Jest will create a snapshot file. Next time you run tests, it will compare the current UI to the saved snapshot.
π Mocking Functions
Sometimes, you need to mock functions to isolate your component's behavior.
Greeting.js
import React, { useEffect, useState } from 'react';
const Greeting = ({ fetchGreeting }) => {
const [greeting, setGreeting] = useState('');
useEffect(() => {
fetchGreeting().then(setGreeting);
}, [fetchGreeting]);
return <h1>{greeting}</h1>;
};
export default Greeting;
Greeting.test.js
import React from 'react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import Greeting from './Greeting';
test('renders greeting from API', async () => {
const mockFetchGreeting = jest.fn().mockResolvedValue('Hello, Jest!');
render(<Greeting fetchGreeting={mockFetchGreeting} />);
const greetingElement = await screen.findByText('Hello, Jest!');
expect(greetingElement).toBeInTheDocument();
});
π Tips for Better Testing
- Test Behavior, Not Implementation: Focus on what the component does, not how it does it.
- Keep Tests Isolated: Donβt let tests depend on each other.
-
Use
beforeEach
for Repeated Setup: Clean and DRY code! π‘
π Your Challenge!
Now itβs your turn! π Create a TodoList
component with the following features:
- Display a list of tasks.
- Add new tasks.
- Mark tasks as completed.
For code you can take reference from this blog of mine:
Reactjs Todo List App (Using Vite & Zustand)
Jagroop Singh γ» Sep 16 '24
Challenge: Write unit tests for each feature! Share your code in the comments πβ¨
Happy Testing! π‘π Let me know how your testing journey goes! π
Top comments (6)
Unit testing is the secret ingredient to good code.
So many time it's tempting to skip it to save time. "I know it works" , "It's just a prototype" whatever your usual excuse is . Dont skip your unit tests
If you keep writing tests along side your code you'll hit moments when it suddently catches a failure or bug you didn't spot.
Unit testing doesn't slow down development - it speeds it up.
Oh, top tip - get IDE extension like the test runners in VSCode that can auto run your tests for you. It's awesome seeing red checks turn green before your eyes.
@drstrangelug , Writing unit tests not only catches hidden bugs early but also boosts long-term development speed and confidence. π
Migrated all my projects from Jest to Vitest. Much faster, much better support for modern codebases - much easier to configure.
sounds interesting !!
let me try Vitest.
Your blogs makes complicated stuffs to easy to understand concepts about new things. I really understand each and every part of this blog. I will try this on Todo List App.
Thanks @paxnw