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

包含useRouteMatch的React组件如何用React Testing Library编写单元测试

报错原因
  • useRouteMatch是react-router-dom提供的路由相关Hook,必须在Router组件的上下文环境中运行,你当前的测试代码没有给组件提供路由上下文,所以触发Hook运行报错
  • 另外组件使用createPortal需要DOM中提前存在id匹配传入myId的节点,否则组件会直接返回null,无法正常完成渲染
解决方案1:使用MemoryRouter包裹测试组件(官方推荐)

这种方式更贴近组件真实运行场景,不需要手动mock路由逻辑,修改后的测试代码如下:

import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { MyComponent } from './my-component';

describe('MyComponent', () => {
  const testId = 'default-id';
  const link = '/route';

  // 提前创建createPortal需要的挂载节点
  beforeEach(() => {
    const portalRoot = document.createElement('ol');
    portalRoot.id = testId;
    document.body.appendChild(portalRoot);
  });

  // 测试完成后清理节点
  afterEach(() => {
    const portalRoot = document.getElementById(testId);
    if (portalRoot) document.body.removeChild(portalRoot);
  });

  it('should render MyComponent successfully', () => {
    // 用MemoryRouter包裹组件提供路由上下文
    render(
      <MemoryRouter>
        <MyComponent myId={testId} link={link}>测试内容</MyComponent>
      </MemoryRouter>
    );
    expect(screen.getByText('测试内容')).toBeInTheDocument();
  });
});
解决方案2:手动mock useRouteMatch

如果你不需要测试路由相关逻辑,只想快速绕过上下文校验,可以直接mock对应的Hook:

import { render, screen } from '@testing-library/react';
import { MyComponent } from './my-component';

// mock react-router-dom的相关方法
jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useRouteMatch: () => ({ url: '/mock-url' }),
  // 也可以顺便mock Link避免其他路由相关报错
  Link: ({ to, children }: { to: string; children: React.ReactNode }) => <a href={to}>{children}</a>
}))

describe('MyComponent', () => {
  const testId = 'default-id';
  const link = '/route';

  beforeEach(() => {
    const portalRoot = document.createElement('ol');
    portalRoot.id = testId;
    document.body.appendChild(portalRoot);
  });

  afterEach(() => {
    const portalRoot = document.getElementById(testId);
    if (portalRoot) document.body.removeChild(portalRoot);
  });

  it('should render MyComponent successfully', () => {
    const element = render(<MyComponent myId={testId} link={link} />);
    expect(element).toBeTruthy();
  });
});

两种方案都可以解决useRouteMatch的报错问题,优先推荐第一种方案,测试结果更贴近组件真实运行表现。

内容的提问来源于stack exchange,提问作者Leo Messi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 03:54:04