使用React Router v6.14.2,我已經(jīng)完成了設(shè)置瀏覽器路由的所有步驟
index.jsx
const router = createBrowserRouter([ { path: "/", element: <App />, children: [ { path: "/", element: <ProfileList />, loader: profileListLoader, }, ], }, ]); const root = ReactDOM.createRoot( document.getElementById("root") as HTMLElement ); root.render(<RouterProvider router={router} />);
然后,當(dāng)我想在我的React組件中使用數(shù)據(jù)加載器時(shí),代碼如下
profileList.jsx
const ProfileList: React.FC = () => { const users = useLoaderData(); return ( <div data-testid={"profiles"}> {users.map((user: User) => ( <Link to={`/profile/${user.id}`}> <ProfileDetailView user={user} /> </Link> ))} </div> ); }; export const profileListLoader = async () => { return fakeUsers as User[]; }; export default ProfileList;
在本地運(yùn)行應(yīng)用程序時(shí),這個(gè)方法非常有效,用戶正在加載,控制臺(tái)或其他地方?jīng)]有任何問(wèn)題。
但是,當(dāng)我嘗試運(yùn)行jest測(cè)試時(shí),我收到以下錯(cuò)誤信息
useLoaderData必須在數(shù)據(jù)路由器中使用
并且指向以下代碼行
const users = useLoaderData();
目前,測(cè)試非常簡(jiǎn)單,但仍然導(dǎo)致測(cè)試失敗。
profile.test.js
test("Render profile list", () => { beforeEach(() => fetch.mockClear()); render(<ProfileList />); const profileList = screen.getByTestId("profiles"); expect(profileList).toBeInTheDocument(); });
我嘗試查看React Router的文檔并且嚴(yán)格按照其中的步驟進(jìn)行操作。我在Stack Overflow上進(jìn)行了搜索,但沒(méi)有找到與我的問(wèn)題完全匹配的內(nèi)容。
即使在單元測(cè)試中,訪問(wèn)數(shù)據(jù)API的組件仍然應(yīng)該在數(shù)據(jù)路由器內(nèi)渲染。在單元測(cè)試中,建議使用MemoryRouter
(例如:createMemoryRouter
),因?yàn)镹ode不是一個(gè)DOM環(huán)境。
示例:
test("Render profile list", () => { beforeEach(() => fetch.mockClear()); const router = createMemoryRouter( [{ path: "/", element:}], { initialEntries: ["/"] }, ); render( ); const profileList = screen.getByTestId("profiles"); expect(profileList).toBeInTheDocument(); });