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

使用Jest、Enzyme与fetch-mock测试React<User>组件时遇重复路由报错

解决fetch-mock路由重复注册的测试报错问题

看起来你遇到的是个很典型的测试环境问题——在多个测试用例里重复注册了同名的fetch-mock路由,而fetch-mock默认不允许这种操作,所以抛出了Adding route with same name as existing route的错误。下面给你几个具体的解决方案:

1. 每个测试后重置fetch-mock(推荐)

Jest提供的afterEach钩子可以帮你在每个测试用例执行完毕后,重置fetch-mock的所有路由和状态,让每个测试都从干净的环境开始,彻底避免路由冲突。

示例代码:

import fetchMock from 'fetch-mock';
import { shallow } from 'enzyme';
import User from './User';

describe('User组件测试', () => {
  // 每个测试结束后重置fetch-mock的状态
  afterEach(() => {
    fetchMock.reset();
  });

  test('获取数据前显示加载文本', () => {
    fetchMock.get('/api/user', { delay: 1000, body: {} });
    const wrapper = shallow(<User />);
    expect(wrapper.text()).toContain('加载中...');
  });

  test('获取数据后显示数据', async () => {
    // 这里可以安全注册相同路由,因为上一个测试已经完成了重置
    fetchMock.get('/api/user', { body: { name: '张三', age: 25 } });
    const wrapper = shallow(<User />);
    
    // 注意:异步请求需要等待组件更新后再断言
    await new Promise(resolve => setTimeout(resolve, 0));
    wrapper.update();
    
    expect(wrapper.text()).toContain('张三');
  });
});

2. 强制覆盖已存在的路由

如果你不想每次都重置,也可以在添加路由时传入overwriteRoutes: true选项,允许fetch-mock直接覆盖同名的已有路由:

// 在第二个测试用例中添加路由时带上该选项
fetchMock.get('/api/user', { body: { name: '张三', age: 25 } }, { overwriteRoutes: true });

3. 使用独立的fetch-mock实例

如果你的测试场景比较复杂,也可以为每个测试创建独立的fetch-mock实例,彻底隔离全局状态的污染:

import fetchMock from 'fetch-mock';
import { shallow } from 'enzyme';
import User from './User';

describe('User组件测试', () => {
  let mockFetch;

  // 每个测试前创建新实例并全局替换fetch
  beforeEach(() => {
    mockFetch = fetchMock.createInstance();
    mockFetch.mockGlobal();
  });

  // 每个测试后恢复原生fetch并清理实例
  afterEach(() => {
    mockFetch.restore();
  });

  test('获取数据前显示加载文本', () => {
    mockFetch.get('/api/user', { delay: 1000, body: {} });
    const wrapper = shallow(<User />);
    expect(wrapper.text()).toContain('加载中...');
  });

  test('获取数据后显示数据', async () => {
    mockFetch.get('/api/user', { body: { name: '张三', age: 25 } });
    const wrapper = shallow(<User />);
    
    await new Promise(resolve => setTimeout(resolve, 0));
    wrapper.update();
    
    expect(wrapper.text()).toContain('张三');
  });
});

额外提醒:异步测试的正确处理

你的第二个测试是验证异步获取数据后的状态,一定要记得等待组件完成异步更新后再进行断言。上面的示例用了setTimeout配合async/await,你也可以使用Enzyme的waitFor方法(Enzyme 3+版本支持),或者Jest的done回调来处理异步逻辑。

内容的提问来源于stack exchange,提问作者Amen Ra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:11:00