How to mock multiple usestate in jest

Mocking Multiple useState in Jest

When writing tests using Jest, you may come across situations where you need to mock multiple useState hooks in order to control their values and test different scenarios. In this guide, we will explain how to mock multiple useState hooks in Jest and provide examples to illustrate the process.

Example Component


import React, { useState } from 'react';

const MyComponent = () => {
    const [count, setCount] = useState(0);
    const [text, setText] = useState("");

    const handleCountIncrement = () => {
        setCount(count + 1);
    };

    return (
        

Count: {count}

setText(event.target.value)} />
); }; export default MyComponent;

Mocking useState with jest.fn()

One way to mock useState in Jest is by using the jest.fn() function. This function creates a new mock function that can replace the original useState implementation during testing.

To mock multiple useState hooks, you can create separate mock functions for each hook and define their return values using the mockReturnValueOnce method.


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

test('Test MyComponent', () => {
    const setCountMock = jest.fn();
    const setTextMock = jest.fn();

    jest.spyOn(React, 'useState').mockReturnValueOnce([0, setCountMock]).mockReturnValueOnce(["", setTextMock]);

    const { getByText, getByLabelText } = render();

    // Test initial render
    expect(getByText("Count: 0")).toBeInTheDocument();
    expect(getByLabelText("input-text")).toHaveValue("");

    // Test button click
    fireEvent.click(getByText("Increment"));
    expect(setCountMock).toHaveBeenCalledWith(1);

    // Test text input
    fireEvent.change(getByLabelText("input-text"), { target: { value: "Hello" } });
    expect(setTextMock).toHaveBeenCalledWith("Hello");
});
    

In the above example, we first create mock functions, setCountMock and setTextMock, using the jest.fn() function. Then, we use jest.spyOn() to mock the useState hook in the React module, returning the mock functions and initial values of the state variables.

Using the render function from the @testing-library/react library, we render the MyComponent and retrieve the necessary elements for testing using getByText and getByLabelText.

We can then simulate a button click using fireEvent.click and verify that the setCountMock function is called with the expected argument.

Similarly, we can simulate a text input change using fireEvent.change and verify that the setTextMock function is called with the expected argument.

Overall, this approach allows us to control the values of multiple useState hooks within the component and test different scenarios.

Leave a comment