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

如何用Jest测试useSelector?新手求助Redux数据获取测试

测试MealsSummary.tsx从Redux获取items的方法

第一步:检查你的useSelector mock是否正确

正确的mock方式应该只覆盖useSelector,保留react-redux的其他导出(比如useDispatch、Provider等),避免影响其他测试逻辑。示例代码如下:

// 测试文件顶部
import { useSelector } from 'react-redux';

// Mock react-redux,只替换useSelector为jest mock函数
jest.mock('react-redux', () => ({
  ...jest.requireActual('react-redux'), // 保留原模块的其他导出
  useSelector: jest.fn(),
}));

如果你的mock没有用...jest.requireActual('react-redux'),而是直接返回{ useSelector: jest.fn() },会导致其他依赖react-redux的功能(比如组件用了useDispatch)失效,这是常见的错误点。

第二步:测试useSelector的mock逻辑

当mock设置正确后,按以下步骤测试:

1. 预设mock返回值

在测试用例前(比如beforeEach中),模拟Redux store的状态,让useSelector返回你需要的items数据:

const mockMealsItems = [
  { id: 1, name: '番茄意面', price: 28 },
  { id: 2, name: '烤鸡沙拉', price: 32 }
];

beforeEach(() => {
  // 重置mock,避免用例间互相影响
  (useSelector as jest.Mock).mockClear();
  
  // 模拟selector函数的调用:传入store状态,返回对应items
  (useSelector as jest.Mock).mockImplementation((selector) => {
    return selector({ meals: { items: mockMealsItems } });
  });
  
  // 如果你的组件直接用useSelector取items,也可以直接简化为:
  // (useSelector as jest.Mock).mockReturnValue(mockMealsItems);
});

2. 渲染组件并断言UI表现

用React Testing Library渲染组件,检查UI是否正确展示了从mock store获取的items:

import { render, screen } from '@testing-library/react';
import MealsSummary from './MealsSummary';

test('正确渲染Redux store中的餐品列表', () => {
  render(<MealsSummary />);
  
  // 断言餐品数量匹配
  const mealItems = screen.getAllByTestId('meal-item'); // 假设组件给每个餐品加了data-testid="meal-item"
  expect(mealItems).toHaveLength(mockMealsItems.length);
  
  // 断言具体餐品信息正确显示
  expect(screen.getByText('番茄意面')).toBeInTheDocument();
  expect(screen.getByText('¥28')).toBeInTheDocument();
});

3. 断言useSelector的调用正确性

如果你想确保组件用了正确的selector函数,可以断言useSelector的调用参数和次数:

// 假设你的项目中有单独的selector函数,比如:
// export const selectMealsItems = (state) => state.meals.items;
import { selectMealsItems } from '../store/mealsSlice';

test('调用useSelector时传入正确的selector函数', () => {
  render(<MealsSummary />);
  
  // 断言useSelector被调用了一次,且参数是selectMealsItems
  expect(useSelector).toHaveBeenCalledTimes(1);
  expect(useSelector).toHaveBeenCalledWith(selectMealsItems);
});

常见注意事项

  • 每次测试前记得用mockClear()重置mock函数,避免不同用例的状态污染。
  • 如果组件依赖Redux的Provider,但你已经mock了useSelector,就不需要再包裹Provider,因为useSelector已经被mock,不会真的去连接store。

内容的提问来源于stack exchange,提问作者benwl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 16:30:59