In jest : "could not find react-redux context value; please ensure the component is wrapped in a <Provider>"

Viewed 2542

I get this error when trying to execute simple Jest test with a form React component :

  ● <LoginForm /> › clicking the validate button › should display page title                              
                                                                                                          
    could not find react-redux context value; please ensure the component is wrapped in a <Provider>      
                                                                                                          
      14 |      const [inputPassword, setInputPassword] = useState("");                                   
      15 |                                                                                                
    > 16 |      const dispatch = useDispatch(); 

Here is the component itself :

import React, { useState, useEffect } from "react";
import { useDispatch } from "react-redux";
import { useHistory } from "react-router-dom";
import jwt_decode from "jwt-decode";
import Cookies from "js-cookie";

import post from "../../../services/request/Post";
import { setCurrentUser } from "../../../redux/action";
import "./index.scss";

const LoginForm = () => {
    const [userData, setUserData] = useState(null);
    const [inputEmail, setInputEmail] = useState("");
    const [inputPassword, setInputPassword] = useState("");

    const dispatch = useDispatch();
    const history = useHistory();

    const handleEmailChange = (e) => {
        setInputEmail(e.target.value);
    };

    const handlePasswordChange = (e) => {
        setInputPassword(e.target.value);
    };

    const handleSubmit = (e) => {
        e.preventDefault();
        setUserData({
            ...userData,
            email: inputEmail,
            password: inputPassword
        });
    };

    const handleLogin = async (data) => {
        if (data) {
            let body = {
                user: { email: data.email, password: data.password }
            };
            const response = await post("/tokens", body);
            if (response != null) {
                Cookies.set("token", response.data.token, {
                    sameSite: "strict",
                    Secure: true
                });
                const payload = {
                    type: "user",
                    id: jwt_decode(response.data.token).user_id,
                    email: userData.email,
                    username: response.data.username
                };
                dispatch(setCurrentUser(payload));
                history.push("/");
            }
        }
    };

    useEffect(() => {
        handleLogin(userData);
    }, [userData]);

    return (
        <div className="LoginForm">
            <form action="" onSubmit={handleSubmit}>
                <label htmlFor="email">Adresse email</label>
                <input
                    type="email"
                    id="email"
                    name="email"
                    value={inputEmail}
                    onChange={handleEmailChange}
                />

                <label htmlFor="password">Mot de passe</label>
                <input
                    type="password"
                    id="password"
                    name="password"
                    value={inputPassword}
                    onChange={handlePasswordChange}
                />

                <button type="submit" id="submitButton">
                    Valider
                </button>
            </form>
        </div>
    );
};

export default LoginForm;

Here is the main.jsx component (the entry point):

ReactDOM.render(
    <React.StrictMode>
        <Provider store={store}>
            <PersistGate loading={null} persistor={persistor}>
                <App />
            </PersistGate>
        </Provider>
    </React.StrictMode>,
    document.getElementById("root")
);

As one can see, I already wrapped the <App /> component in a <Provider>

Finally, here is the quite simple test I wrote:

import React from 'react';
import { render, screen } from "@testing-library/react";
// import userEvent from "@testing-library/user-event";

import LoginForm from '../components/forms/LoginForm';

describe('<LoginForm />', () => {
  describe('clicking the validate button', () => {
    beforeEach(
      render(<LoginForm />)
    );

    it("should display page title", () => {
      expect(screen.getByText("Page de connexion")).toBeInTheDocument();
      expect(screen.getByText("Adresse email")).toBeInTheDocument();
      expect(screen.getByText("Mot de passe")).toBeInTheDocument();
    })
  });
});

It is the first time I write test with React so I am kinda lost. Should I use a sort of mock store for testing environments ? If so, is it possible to do it globally, for every tested components ?

2 Answers
Related