如何使用Jest与RTL测试React中的错误路由及404页面?
解决React Router v6 + Jest/RTL测试404路由的错误问题
问题根源
你遇到的TypeError: Cannot read properties of undefined (reading 'pathname')错误主要来自两个问题:
- React Router v6的BrowserRouter不支持传入history prop:测试代码中用
<Router history={history}>包裹了已经内置BrowserRouter的App,两层路由组件冲突导致上下文异常。 - App中的路由路径格式错误:你写的
path="#path2"是HTML锚点格式,不是React Router的标准路由路径,会导致路由匹配逻辑失效。
修复步骤
1. 修正App中的路由路径
把所有带#的路径改成标准路由格式,并将Router移到App组件外部:
// App.js import { Routes, Route } from "react-router-dom"; import "./styles/index.css"; function App() { return ( <Routes> <Route path="/" element={<MainComp />} /> <Route path="/path2" element={<Comp2/>} /> <Route path="/path3" element={<Comp3/>} /> <Route path="/path4" element={<Comp4/>} /> <Route path="*" element={<NoMatch />} /> </Routes> ); }
在入口文件(比如index.js)中包裹Router:
// index.js import { BrowserRouter as Router } from "react-router-dom"; import App from "./App"; import ReactDOM from 'react-dom/client'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <Router> <App /> </Router> );
2. 重写测试代码
利用MemoryRouter的initialEntries直接设置测试路由,同时用RTL的findByText(自带异步等待逻辑)简化测试:
import { MemoryRouter } from 'react-router-dom'; import { render, screen } from '@testing-library/react'; import App from './App'; test('路由不匹配时渲染404页面', async () => { render( <MemoryRouter initialEntries={['/bad/route']}> <App /> </MemoryRouter> ); // findByText自动等待元素出现,无需额外waitFor expect(await screen.findByText(/page that doesn't exist./i)).toBeInTheDocument(); });
方案说明
- 将Router从App中抽离后,测试时可灵活替换为
MemoryRouter,避免生产环境路由组件与测试路由组件的冲突。 initialEntries直接指定初始路由,无需手动操作history对象,符合React Router v6的测试最佳实践。findByText是RTL推荐的异步查询方式,内部集成了等待逻辑,简化了测试代码结构。
内容的提问来源于stack exchange,提问作者user
相关产品推荐
相关产品推荐

