lzl*_*31x 9 reactjs react-router react-router-dom react-testing-library
我按照本教程从 React Router v5 迁移到 v6 。我想用react-testing-library来测试它,但是我的旧单元测试(使用本文档中的模式)停止工作。
我的 React Router v6 应用程序是这样的
const router = createBrowserRouter([
{
path: "/",
element: (
<>
<SiteHeader />
<Outlet />
</>
),
errorElement: <NotFound />,
children: [
{ path: "/", element: <Home /> },
{ path: "/posts", element: <Posts /> },
{ path: "/post/:postId", element: <PostPage /> },
],
},
]);
function App() {
return (
<div className="app">
<RouterProvider router={router} />
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,它使用RouterProvider而不是Switch/ Route(所以我很困惑,这个SO 问题说它使用的是 React Router v6,但它看起来很不同。)。
测试库官方文档中的代码也没有使用RouterProvider。
我想测试一些路由逻辑,如以下伪代码:
renderWithRouter(<App />, "/posts"); // loads /posts page initially
await user.click(screen.getByText("some post title")); // trigger click
expect(getUrl(location)).toEqual("/post/123"); // checks the URL changed correctly
Run Code Online (Sandbox Code Playgroud)
我怎样才能创建这样的renderWithRouter函数?RouterProvider请注意,当我使用 React Router v5 时,这对我有用,但在迁移到 v6 后,它停止工作。renderWithRouter
我当前的依赖版本:
我试过这个
test("click post goes to /post/:postId", async () => {
render(
<MemoryRouter initialEntries={["/posts"]}>
<App />
</MemoryRouter>,
);
// ...
});
Run Code Online (Sandbox Code Playgroud)
但我得到了错误
You cannot render a <Router> inside another <Router>. You should never have more than one in your app.
31 | test("click post goes to /post/:postId", async () => {
> 32 | render(
| ^
34 | <MemoryRouter initialEntries={["/posts"]}>
36 | <App />
Run Code Online (Sandbox Code Playgroud)
Dre*_*ese 15
如果您想使用新的数据路由器来测试整个路由配置react-router-dom@6.4,那么我建议对代码进行一些重构,以允许能够存根进行MemoryRouter任何单元测试。
自行声明路由配置并导出。
const routesConfig = [
{
path: "/",
element: (
<>
<SiteHeader />
<Outlet />
</>
),
errorElement: <NotFound />,
children: [
{ path: "/", element: <Home /> },
{ path: "/posts", element: <Posts /> },
{ path: "/post/:postId", element: <PostPage /> },
],
},
];
export default routesConfig;
Run Code Online (Sandbox Code Playgroud)
在应用程序代码中导入routesConfig并实例化BrowserRouter应用程序使用的。
import {
RouterProvider,
createBrowserRouter,
} from "react-router-dom";
import routesConfig from '../routes';
const router = createBrowserRouter(routesConfig);
function App() {
return (
<div className="app">
<RouterProvider router={router} />
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
对于单元测试,导入routesConfig并实例化MemoryRouter.
import {
RouterProvider,
createMemoryRouter,
} from "react-router-dom";
import { render, waitFor } from "@testing-library/react";
import routesConfig from '../routes';
...
test("click post goes to /post/:postId", async () => {
const router = createMemoryRouter(routesConfig, {
initialEntries: ["/posts"],
});
render(<RouterProvider router={router} />);
// make assertions, await changes, etc...
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16885 次 |
| 最近记录: |