How to Perform Unit Testing in React Components with Examples?

Author: neptune | 25th-Jul-2024

Unit testing is crucial in ensuring that individual components of your application work as expected. In React, unit testing can be efficiently performed using tools like Jest and the React Testing Library. This article will guide you through the basics of unit testing React components, complete with an example.


Prerequisites

Before you start, ensure you have the following:


1. Node.js installed.

2. A React application set up (you can use Create React App).

3. Jest and React Testing Library installed.


You can install Jest and React Testing Library with the following command:


    npm install --save-dev jest @testing-library/react @testing-library/jest-dom



Setting Up Testing Environment

Create React App comes with Jest pre-configured, so you can start writing tests without any additional setup. If you are using a custom setup, you may need to configure Jest manually by adding a `jest.config.js` file.


Writing Your First Test

Let's start with a simple React component:


    // src/components/Greeting.js

    import React from 'react';


    const Greeting = ({ name }) => {

        return <h1>Hello, {name}!</h1>;

    };


    export default Greeting;



Now, let's write a unit test for this component:


    // src/components/Greeting.test.js

    import React from 'react';

    import { render } from '@testing-library/react';

    import '@testing-library/jest-dom/extend-expect';

    import Greeting from './Greeting';


    test('renders greeting message', () => {

        const { getByText } = render(<Greeting name="John" />);

        expect(getByText('Hello, John!')).toBeInTheDocument();

    });



Explanation

1. Importing Dependencies: We import React, the `render` function from React Testing Library, and the `Greeting` component. The `@testing-library/jest-dom/extend-expect` library provides additional matchers for Jest.


2. Writing the Test Case: The `test` function defines a single test case. It takes a string description and a function containing the test logic.


3. Rendering the Component: We use the `render` function from React Testing Library to render the `Greeting` component.


4. Asserting the Output: We use the `getByText` query to find the text content in the rendered output and then assert that it is present in the document using the `toBeInTheDocument` matcher.


Testing User Interactions

Let's consider a more interactive component:

    // src/components/Counter.js

    import React, { useState } from 'react';


    const Counter = () => {

        const [count, setCount] = useState(0);


        return (

            <div>

                <p>You clicked {count} times</p>

                <button onClick={() => setCount(count + 1)}>Click me</button>

            </div>

        );

    };


    export default Counter;



Now, let's write tests for the `Counter` component:


    // src/components/Counter.test.js

    import React from 'react';

    import { render, fireEvent } from '@testing-library/react';

    import '@testing-library/jest-dom/extend-expect';

    import Counter from './Counter';


    test('renders counter with initial state', () => {

        const { getByText } = render(<Counter />);

        expect(getByText('You clicked 0 times')).toBeInTheDocument();

    });


    test('increments counter on button click', () => {

        const { getByText } = render(<Counter />);

        const button = getByText('Click me');


        fireEvent.click(button);

        expect(getByText('You clicked 1 time')).toBeInTheDocument();


        fireEvent.click(button);

        expect(getByText('You clicked 2 times')).toBeInTheDocument();

    });



Explanation

1. Rendering the Component: The `render` function renders the `Counter` component.


2. Initial State Check: We assert that the initial state of the counter is 0.


3. Simulating User Interaction: We use the `fireEvent.click` function to simulate a button click and then assert that the counter increments correctly.


Mocking API Calls

For components that make API calls, you can use Jest's mocking capabilities. Here is an example:


    // src/components/User.js

    import React, { useState, useEffect } from 'react';


    const User = () => {

        const [user, setUser] = useState(null);


        useEffect(() => {

            fetch('/api/user')

                .then(response => response.json())

                .then(data => setUser(data));

        }, []);


        if (!user) return <div>Loading...</div>;


        return <div>Hello, {user.name}</div>;

    };


    export default User;



Now, let's write tests for the `User` component:


    // src/components/User.test.js

    import React from 'react';

    import { render, waitFor } from '@testing-library/react';

    import '@testing-library/jest-dom/extend-expect';

    import User from './User';


    beforeEach(() => {

        fetch.resetMocks();

    });


    test('renders user data after fetching', async () => {

        fetch.mockResponseOnce(JSON.stringify({ name: 'John Doe' }));


        const { getByText } = render(<User />);

        expect(getByText('Loading...')).toBeInTheDocument();


        await waitFor(() => expect(getByText('Hello, John Doe')).toBeInTheDocument());

    });



Explanation

1. Mocking Fetch: We mock the fetch API using `jest-fetch-mock`.


2. Asserting Initial Loading State: We assert that the initial state shows a loading message.


3. Waiting for Data: We use `waitFor` to wait for the asynchronous fetch call to complete and then assert that the component renders the fetched data correctly.


Conclusion

Unit testing in React is an essential practice to ensure the reliability and robustness of your components. Using Jest and the React Testing Library, you can write comprehensive tests that cover rendering, user interactions, and even asynchronous operations. By following the examples provided, you can start building a solid suite of tests for your React application, leading to higher code quality and easier maintenance.




👉 Read More
React: Slideshow App | Fresco Play Hackerrank
Generate Fibonacci Sequence - JavaScript | Hackerank
Managing Virtual Environments in React JavaScript Projects
To Be Or Not To Be | #2704 | LeetCode Solution
Apply Transform Over Each Element in Array | #2635 | LeetCode Solution
Create Your First App in React with Redux | Counter app
Function Composition | #2629 | LeetCode Solution
Essential Topics to Master React JS
Counter | #2620 | LeetCode Solution
Different ways to handle state in React applications
React.js vs React Native – What's the Difference?
Chunk Array | #2677 | LeetCode Solution
Counter 2 | #2665 | LeetCode Solution
Array Reduce Transformation | #2626 | LeetCode Solution
Add Two Promises | #2723 | LeetCode Solution
Filter Elements from Array | #2634 | LeetCode Solution
Why React Refuses to Die ?
Opportunities - React Django Developer
😱 How React Kicks Off OOPs ? 😱
Arrow Functions in JavaScript | ES6
From REST to GraphQL: The Future of API Design
Is Object Empty | #2727 | LeetCode | JavaScript Solution
Celebrating 10 Years of React: A Decade of Innovation
How I Built My Blogging Website Using React, Node.js, and Jamstack Architecture?
Do you know ! How to manage State in Functional & Class Components in React ?
A Guide to Writing Clean, Readable, and Maintainable Code in JavaScript
How to Get Started with Jamstack: A Comprehensive Guide?
Why, What, and When: Understanding Jamstack?
Explore more Blogs...