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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 04:55:18