You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 08:45:10