React Router v6测试中BrowserRouter如何设置初始路由为/signup
方案1:使用history.pushState修改初始路径(最简便,无额外依赖)
你遇到的jsdom报错是因为直接修改window.location.href会触发全页面重定向,jsdom未实现该能力,但无刷新的history API是支持的。只需要在渲染组件前调用pushState修改当前路径即可,代码改动很小:
import React from 'react'; import userEvent from '@testing-library/user-event'; // 替换导入为BrowserRouter import { BrowserRouter, Route, Routes } from 'react-router-dom'; import { render, screen } from '../../test/test-utils'; import { SignUpPage } from './SignUpPage'; const MockHomePage = () => <div>MockHomePage</div>; describe('<SignUp />', () => { test('navigates to Home page on successful signup', async () => { // 新增这行,无刷新修改当前路径为/signup window.history.pushState({}, '', '/signup'); render( <BrowserRouter> <Routes> <Route path="/" element={<MockHomePage />} /> <Route path="/signup" element={<SignUpPage />} /> </Routes> </BrowserRouter> ); // 后面的测试逻辑完全不用改 userEvent.type(screen.getByLabelText('Full Name'), 'John Smith'); userEvent.type(screen.getByLabelText('Email'), 'johnsmith@gmail.com'); userEvent.type(screen.getByLabelText('Password'), 'let-me-in'); userEvent.type(screen.getByLabelText('Confirm Password'), 'let-me-in'); userEvent.click(screen.getByText('Sign up')); expect(await screen.findByText('MockHomePage')).toBeInTheDocument(); }); });
该方案对现有代码改动最小,不需要额外安装依赖,完全符合你用BrowserRouter贴近真实场景的需求。
方案2:通过jest配置全局设置测试默认URL
如果有多个测试都需要指定初始路径,可以直接在jest配置文件(jest.config.js)里添加testURL配置:
module.exports = { // 其他配置保持不变 testURL: 'http://localhost:3000/signup' }
这样所有测试运行时的默认路径就是/signup,测试代码里不需要额外加pushState逻辑,直接用BrowserRouter即可。如果不同测试需要不同路径,还是用第一种方案更灵活。
方案3:自定义封装基于createBrowserHistory的Router
如果需要更灵活的路由控制(比如监听路由变化、手动跳转等),可以用React Router v6暴露的底层Router组件,配合history库的createBrowserHistory手动传入路由实例:
- 先安装对应版本的history库:
npm install history@5 --save-dev
- 测试代码示例:
import React from 'react'; import userEvent from '@testing-library/user-event'; // 导入底层Router组件 import { Router, Route, Routes } from 'react-router-dom'; import { createBrowserHistory } from 'history'; import { render, screen } from '../../test/test-utils'; import { SignUpPage } from './SignUpPage'; const MockHomePage = () => <div>MockHomePage</div>; describe('<SignUp />', () => { test('navigates to Home page on successful signup', async () => { // 创建浏览器history实例,指定初始路径 const history = createBrowserHistory({ initialEntries: ['/signup'] }); render( <Router location={history.location} navigator={history}> <Routes> <Route path="/" element={<MockHomePage />} /> <Route path="/signup" element={<SignUpPage />} /> </Routes> </Router> ); // 后续测试逻辑保持不变 userEvent.type(screen.getByLabelText('Full Name'), 'John Smith'); userEvent.type(screen.getByLabelText('Email'), 'johnsmith@gmail.com'); userEvent.type(screen.getByLabelText('Password'), 'let-me-in'); userEvent.type(screen.getByLabelText('Confirm Password'), 'let-me-in'); userEvent.click(screen.getByText('Sign up')); expect(await screen.findByText('MockHomePage')).toBeInTheDocument(); }); });
该方案灵活性最高,适合有复杂路由测试需求的场景。
内容的提问来源于stack exchange,提问作者Naresh
相关产品推荐
相关产品推荐

