簡體   English   中英

開玩笑說:“找不到 react-redux 上下文值;請確保組件包裝在<provider> "</provider>

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

嘗試使用表單 React 組件執行簡單的 Jest 測試時出現此錯誤:

  ● <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(); 

這是組件本身:

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;

這是 main.jsx 組件(入口點):

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

如您所見,我已經將<App />組件包裝在<Provider>

最后,這是我寫的一個非常簡單的測試:

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();
    })
  });
});

這是我第一次用 React 編寫測試,所以我有點迷茫。 我應該使用一種模擬商店來測試環境嗎? 如果是這樣,是否可以在全球范圍內為每個測試的組件執行此操作?

是的,您應該用<Provider store={store}>包裝<LoginForm /> <Provider store={store}>

您可以設置一個可重用的函數,它會自動為您執行此操作:

https://redux.js.org/usage/writing-tests#components

In my case, to be able to mock store and provider, I implemented a custom render function named renderWithProviders according to the redux docs to my application that was built using Typescript, Webpack, React-Redux, and Jest.

參考

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM