如何在Jest测试中模拟useSelector数据?React组件测试求助
解决React组件useSelector数据Mock与条件UI测试覆盖问题
方案1:直接Mock useSelector 函数
通过Jest直接mock react-redux 的useSelector,根据不同测试场景返回对应数据,精准触发条件分支。
测试场景1:id存在时,渲染供应商详情区域
import { render, screen } from '@testing-library/react'; import { useSelector } from 'react-redux'; import MyComponent from './MyComponent'; // Mock useSelector jest.mock('react-redux'); test('id存在时渲染供应商详情', () => { useSelector.mockImplementation(selector => { // 匹配原组件中的选择器(注意原代码拼写selecetdId) if (selector.name === 'selecetdId') { return { id: 'supplier-123' }; } if (selector.name === 'data') { return []; } return {}; }); render(<MyComponent />); // 断言目标区域存在 expect(screen.getByClassName('supplier-details')).toBeInTheDocument(); expect(screen.getByRole('heading')).toBeInTheDocument(); // 假设CustomHeader是语义化标题 });
测试场景2:id不存在且dataArray有数据时,渲染CustomTable
test('id不存在且有数据时渲染CustomTable', () => { useSelector.mockImplementation(selector => { if (selector.name === 'selecetdId') { return { id: undefined }; } if (selector.name === 'data') { return [{ id: '1', name: '测试供应商' }, { id: '2', name: '测试供应商2' }]; } return {}; }); render(<MyComponent />); // 断言CustomTable存在(推荐用data-testid标记组件) expect(screen.getByTestId('custom-table')).toBeInTheDocument(); expect(screen.getByTestId('another-custom-component')).toBeInTheDocument(); });
测试场景3:id不存在且dataArray为空时,渲染NoData组件
test('id不存在且无数据时渲染NoData', () => { useSelector.mockImplementation(selector => { if (selector.name === 'selecetdId') { return { id: undefined }; } if (selector.name === 'data') { return []; } return {}; }); render(<MyComponent />); expect(screen.getByTestId('no-data')).toBeInTheDocument(); });
方案2:用redux-mock-store结合Provider
如果组件依赖Redux Provider,可创建模拟Store并传入,更贴近真实Redux环境:
import { render, screen } from '@testing-library/react'; import { Provider } from 'react-redux'; import configureMockStore from 'redux-mock-store'; import MyComponent from './MyComponent'; const mockStore = configureMockStore([]); test('通过Mock Store渲染供应商详情', () => { const store = mockStore({ // 对应你的Redux state结构 selectedId: { id: 'supplier-123' }, data: [] }); render( <Provider store={store}> <MyComponent /> </Provider> ); expect(screen.getByClassName('supplier-details')).toBeInTheDocument(); }); test('通过Mock Store渲染CustomTable', () => { const store = mockStore({ selectedId: { id: undefined }, data: [{ id: '1', name: '测试供应商' }] }); render( <Provider store={store}> <MyComponent /> </Provider> ); expect(screen.getByTestId('custom-table')).toBeInTheDocument(); });
注意事项
- 原代码中
selecetdId存在拼写错误(应为selectedId),建议修正;若暂时无法修改,mock时需严格匹配该拼写。 - 测试优先使用语义化查询(如
getByRole),避免过度依赖className,提升测试稳定性。 - 若
filteredSuppliers是组件内部基于dataArray的处理结果,需确保mock数据能生成预期的filteredSuppliers,或单独测试该过滤逻辑。
内容的提问来源于stack exchange,提问作者Aayushi Gupta
相关产品推荐
相关产品推荐

