如何用Jest和Enzyme测试React高阶组件并设置Session状态
解决React高阶组件withSession的单元测试中设置Session状态的问题
方案1:Mock底层的session Observable(推荐,保留HOC逻辑)
withSession依赖@efa/web/src/modules/auth/authService中的session Observable获取会话状态,直接mock这个Observable就能控制它发射的session值:
- 在测试文件顶部添加mock:
import { of } from 'rxjs'; jest.mock('@efa/web/src/modules/auth/authService', () => ({ // 保留原模块的其他导出内容 ...jest.requireActual('@efa/web/src/modules/auth/authService'), // 替换session为我们控制的Observable,同步发射预设的session session: jest.fn(() => of({ id: '2' })) }));
- 编写测试用例:
it('renders correctly', async () => { const Component = withEverything(Header); const wrapper = mount(<Component componentProps={{}} />); // 等待组件完成状态更新并渲染目标组件 await waitFor(() => { expect(wrapper.find(Header)).toBeTruthy(); // 断言Header组件接收到了正确的session expect(wrapper.find(Header).props().session).toEqual({ id: '2' }); }); console.log(wrapper.debug()); });
方案2:改进withSession的Mock,支持自定义Session
如果不需要测试withSession本身的逻辑,只想快速注入session,可以修改mock让它支持传递或预设session:
- 修改mock代码:
jest.mock('@efa/web/src/modules/auth/components/withSession', () => { const original = jest.requireActual('@efa/web/src/modules/auth/components/withSession'); return { __esModule: true, ...original, withSession: (Component) => { // 返回一个组件,优先使用props中的session,否则用预设默认值 return (props) => { const defaultSession = { id: '2' }; const session = props.session || defaultSession; // 合并props并注入session return <Component {...props} session={session} />; }; } }; });
- 测试用例写法:
it('renders correctly', () => { const Component = withEverything(Header); // 可直接传入自定义session覆盖默认值 const wrapper = mount(<Component componentProps={{ session: { id: '3' } }} />); expect(wrapper.find(Header).props().session).toEqual({ id: '3' }); console.log(wrapper.debug()); });
注意事项
- 使用方案1时,确保测试环境已正确引入rxjs的
of操作符。 - 若原HOC在session为
undefined时返回null,mock后的Observable要避免发射undefined,或在测试中等待组件完成状态更新。
内容的提问来源于stack exchange,提问作者tom Bannister
相关产品推荐
相关产品推荐

