升级到 v7 后使用 React 测试库进行测试时,React Router Outlet 未在嵌套路由中渲染

问题描述 投票:0回答:1
import { render, screen, waitFor } from '@testing-library/react'; import React from "react"; import { createMemoryRouter, RouterProvider, Outlet, createBrowserRouter } from 'react-router-dom'; const Layout = () => ( <div> <header>Header</header> <main> <Outlet /> </main> <footer>Footer</footer> </div> ); const routes = [ { path: '/', element: <Layout />, children: [ { path: '/', element: <>home</> }, { path: 'about', element: <>about</> }, ], }, ]; const router = createBrowserRouter(routes); function App() { return <RouterProvider router={router} />; } describe("sample code ", () => { it("test home", async () => { const router1 = createMemoryRouter(routes, { initialEntries: ['/about'] }) render( <RouterProvider router={router1} /> ); expect(screen.getByText(/header/i)).toBeInTheDocument(); await waitFor(() => expect(screen.getByText(/about/i)).toBeInTheDocument()); expect(screen.getByText(/footer/i)).toBeInTheDocument(); }) })
我目前正在使用 React 测试库 (RTL) 中的初始条目来测试路由和嵌套路由。但是,我遇到了一个问题,即 Outlet 组件在我的测试中无法按预期运行,即使它在实际应用程序中运行良好。

reactjs react-router react-testing-library
1个回答
0
投票
我最初能够重现您所描述的测试问题。您此处的相同代码在 React-Router-DOM 6 中运行得非常好,因此在从 v6 到 v7 的主要版本更新中发生了一些不平凡但非常微妙的变化。

我查了一下:

在迁移指南中,他们更详细地讨论了从

v6 到 v7 的弃用和更改。具体来说,最后的“更新 DOM 特定导入”部分描述了 RouterProvider

 从存储库中导出的位置。

👉 更新 DOM 特定的导入

RouterProvider

HydratedRouter
 具有深刻的意义,因为它们
取决于“react-dom”:

-import { RouterProvider } from "react-router-dom"; +import { RouterProvider } from "react-router/dom";
请注意,您应该对非 DOM 上下文使用顶级导入,例如
开玩笑测试:

-import { RouterProvider } from "react-router-dom"; +import { RouterProvider } from "react-router";
恭喜,您现在已进入 v7!

在单元测试代码中,从

react-router

 而不是 
react-router-dom
 导入路由器组件。

import { render, screen } from "@testing-library/react"; import "@testing-library/jest-dom"; import React from "react"; import { createMemoryRouter, RouterProvider, Outlet, createBrowserRouter, } from "react-router"; // <-- Use main React-Router package! const Layout = () => ( <div> <header>Header</header> <main> <Outlet /> </main> <footer>Footer</footer> </div> ); const routes = [ { path: "/", element: <Layout />, children: [ { path: "/", element: <>home</> }, { path: "about", element: <div>about</div> }, ], }, ]; const router = createBrowserRouter(routes); function App() { return <RouterProvider router={router} />; } describe("sample code ", () => { it("test home", async () => { const router1 = createMemoryRouter(routes, { initialEntries: ["/about"] }); render(<RouterProvider router={router1} />); expect(screen.getByText(/header/i)).toBeInTheDocument(); expect(screen.getByText(/about/i)).toBeInTheDocument(); expect(screen.getByText(/footer/i)).toBeInTheDocument(); }); });
尽管 

@remix/react-router

 重新导出所有 
react-router-dom
,但这不包括位于另一个存储库包中的 
RouterProvider
。单独使用 
react-router-dom
 无法获得正确的导入。

从从
react-router-dom
进口
react-router
进口
imports from react-router-dom imports from react-router
© www.soinside.com 2019 - 2024. All rights reserved.