如何使用Jest测试React Router 解决ButtonLogin只读报错问题
问题根因
你原来的测试代码存在4个核心错误:
- 导入错误:
ButtonLogin是默认导出,你用了命名导入语法import { ButtonLogin },无法正确引入组件 - 不可变赋值:ES模块导入的变量是只读的,你直接给
ButtonLogin赋值为jest mock函数必然触发只读报错 - 测试对象错误:你没有渲染目标
ButtonLogin组件,反而手动写了Link标签,完全没有覆盖到要测试的组件逻辑 - 断言逻辑错误:你没有验证路由跳转行为,反而断言
ButtonLogin被调用,和实际逻辑完全不匹配
正确测试代码
方案1:单元测试(验证Link属性,性能最快)
只需要验证ButtonLogin组件渲染的Link标签to属性符合预期即可,不需要模拟点击:
import { render, screen } from '@testing-library/react'; import { MemoryRouter } from 'react-router-dom'; import ButtonLogin from './ButtonLogin'; // 注意是默认导入 it('ButtonLogin renders link to /login', () => { render(<ButtonLogin />, { wrapper: MemoryRouter }); // 找到Link对应的a标签,验证href属性 const loginLink = screen.getByRole('link', { name: /iniciar sesión/i }); expect(loginLink).toHaveAttribute('href', '/login'); });
方案2:交互测试(验证点击跳转行为)
如果需要模拟点击验证跳转效果,可以通过MemoryRouter的路由状态验证:
import { render, screen, fireEvent } from '@testing-library/react'; import { MemoryRouter, Routes, Route } from 'react-router-dom'; import ButtonLogin from './ButtonLogin'; it('routes to /login after click', () => { let currentLocation; render( <MemoryRouter initialEntries={['/']}> <Routes> <Route path="*" element={<ButtonLogin />} /> {/* 捕获当前路由位置 */} <Route path="*" element={({ location }) => { currentLocation = location; return null; }} /> </Routes> </MemoryRouter> ); fireEvent.click(screen.getByRole('button', { name: /iniciar sesión/i })); expect(currentLocation.pathname).toBe('/login'); });
两种方案都可以通过测试,方案1足够覆盖组件逻辑,更推荐作为单元测试使用。
内容的提问来源于stack exchange,提问作者DanielRomero
相关产品推荐
相关产品推荐

