如何使用Jest和Enzyme对搭载Context API与路由的React App做单元测试
路由逻辑单元测试实现方案
前置依赖确认
先确保你已经安装了测试所需的依赖包,对应你的React版本安装适配版本:
npm install --save-dev enzyme enzyme-adapter-react-xx jest-enzyme react-test-renderer
将xx替换为你当前使用的React主版本号,如React16就填16,React18可安装社区维护的适配包@wojtekmaj/enzyme-adapter-react-18。
测试用例编写
在App.js同级目录新建App.test.js,代码如下:
import React from 'react'; import Enzyme, { mount } from 'enzyme'; import { MemoryRouter } from 'react-router-dom'; import App from './App'; import { Provider } from './context'; // mock无关组件,避免引入额外依赖影响路由测试 jest.mock('./components/layout/Navbar', () => () => <div>Navbar</div>); jest.mock('./components/layout/Index', () => () => <div>IndexPage</div>); jest.mock('./components/tracks/Lyrics', () => () => <div>LyricsPage</div>); // 配置enzyme适配器,以下为React16示例,其他版本对应修改导入包 import Adapter from 'enzyme-adapter-react-16'; Enzyme.configure({ adapter: new Adapter() }); describe('App路由逻辑测试', () => { test('根路径/匹配时渲染Index组件', () => { const wrapper = mount( <Provider> <MemoryRouter initialEntries={['/']}> <App /> </MemoryRouter> </Provider> ); expect(wrapper.find('IndexPage').exists()).toBeTruthy(); expect(wrapper.find('LyricsPage').exists()).toBeFalsy(); }); test('歌词路径/lyrics/track/:id匹配时渲染Lyrics组件', () => { const wrapper = mount( <Provider> <MemoryRouter initialEntries={['/lyrics/track/123']}> <App /> </MemoryRouter> </Provider> ); expect(wrapper.find('LyricsPage').exists()).toBeTruthy(); expect(wrapper.find('IndexPage').exists()).toBeFalsy(); }); });
关键注意事项
- 测试路由组件必须使用
mount渲染而非shallow,shallow只会渲染当前组件的第一层子节点,无法触发路由匹配逻辑 - 使用
MemoryRouter替代默认的BrowserRouter,可以通过initialEntries属性自由模拟当前访问路径,不需要依赖浏览器环境 - mock无关的子组件,仅验证路由匹配规则是否生效,避免子组件的内部逻辑干扰当前测试
- 必须包裹你自定义的Context Provider,否则组件内部使用context的代码会报错,若你的Provider需要传入自定义value,可直接在测试代码中给Provider加
value属性传入测试用的模拟数据
内容的提问来源于stack exchange,提问作者godshark
相关产品推荐
相关产品推荐

