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 ?