使用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
相关产品推荐
相关产品推荐

