开玩笑:“找不到react-redux上下文值;请确保组件包装在 <Provider> 中”

Lou*_*Lou 8 javascript reactjs jestjs redux

当尝试使用表单 React 组件执行简单的 Jest 测试时,我收到此错误:

\n
  \xe2\x97\x8f <LoginForm /> \xe2\x80\xba clicking the validate button \xe2\x80\xba should display page title                              \n                                                                                                          \n    could not find react-redux context value; please ensure the component is wrapped in a <Provider>      \n                                                                                                          \n      14 |      const [inputPassword, setInputPassword] = useState("");                                   \n      15 |                                                                                                \n    > 16 |      const dispatch = useDispatch(); \n
Run Code Online (Sandbox Code Playgroud)\n

这是组件本身:

\n
import React, { useState, useEffect } from "react";\nimport { useDispatch } from "react-redux";\nimport { useHistory } from "react-router-dom";\nimport jwt_decode from "jwt-decode";\nimport Cookies from "js-cookie";\n\nimport post from "../../../services/request/Post";\nimport { setCurrentUser } from "../../../redux/action";\nimport "./index.scss";\n\nconst LoginForm = () => {\n    const [userData, setUserData] = useState(null);\n    const [inputEmail, setInputEmail] = useState("");\n    const [inputPassword, setInputPassword] = useState("");\n\n    const dispatch = useDispatch();\n    const history = useHistory();\n\n    const handleEmailChange = (e) => {\n        setInputEmail(e.target.value);\n    };\n\n    const handlePasswordChange = (e) => {\n        setInputPassword(e.target.value);\n    };\n\n    const handleSubmit = (e) => {\n        e.preventDefault();\n        setUserData({\n            ...userData,\n            email: inputEmail,\n            password: inputPassword\n        });\n    };\n\n    const handleLogin = async (data) => {\n        if (data) {\n            let body = {\n                user: { email: data.email, password: data.password }\n            };\n            const response = await post("/tokens", body);\n            if (response != null) {\n                Cookies.set("token", response.data.token, {\n                    sameSite: "strict",\n                    Secure: true\n                });\n                const payload = {\n                    type: "user",\n                    id: jwt_decode(response.data.token).user_id,\n                    email: userData.email,\n                    username: response.data.username\n                };\n                dispatch(setCurrentUser(payload));\n                history.push("/");\n            }\n        }\n    };\n\n    useEffect(() => {\n        handleLogin(userData);\n    }, [userData]);\n\n    return (\n        <div className="LoginForm">\n            <form action="" onSubmit={handleSubmit}>\n                <label htmlFor="email">Adresse email</label>\n                <input\n                    type="email"\n                    id="email"\n                    name="email"\n                    value={inputEmail}\n                    onChange={handleEmailChange}\n                />\n\n                <label htmlFor="password">Mot de passe</label>\n                <input\n                    type="password"\n                    id="password"\n                    name="password"\n                    value={inputPassword}\n                    onChange={handlePasswordChange}\n                />\n\n                <button type="submit" id="submitButton">\n                    Valider\n                </button>\n            </form>\n        </div>\n    );\n};\n\nexport default LoginForm;\n
Run Code Online (Sandbox Code Playgroud)\n

这是 main.jsx 组件(入口点):

\n
ReactDOM.render(\n    <React.StrictMode>\n        <Provider store={store}>\n            <PersistGate loading={null} persistor={persistor}>\n                <App />\n            </PersistGate>\n        </Provider>\n    </React.StrictMode>,\n    document.getElementById("root")\n);\n
Run Code Online (Sandbox Code Playgroud)\n

正如您所看到的,我已经将该<App />组件包装在一个<Provider>

\n

最后,这是我编写的非常简单的测试:

\n
import React from 'react';\nimport { render, screen } from "@testing-library/react";\n// import userEvent from "@testing-library/user-event";\n\nimport LoginForm from '../components/forms/LoginForm';\n\ndescribe('<LoginForm />', () => {\n  describe('clicking the validate button', () => {\n    beforeEach(\n      render(<LoginForm />)\n    );\n\n    it("should display page title", () => {\n      expect(screen.getByText("Page de connexion")).toBeInTheDocument();\n      expect(screen.getByText("Adresse email")).toBeInTheDocument();\n      expect(screen.getByText("Mot de passe")).toBeInTheDocument();\n    })\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n

这是我第一次用 React 编写测试,所以我有点迷失。我应该使用某种模拟商店来测试环境吗?如果是这样,是否可以在全球范围内对每个测试组件进行此操作?

\n

mar*_*son 7

是的,你应该<LoginForm /><Provider store={store}>.

您可以设置一个可重用的函数,它会自动为您执行此操作:

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