如何用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
相关产品推荐
相关产品推荐

