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

升级Jest至v29后Reselect选择器Mock失效问题求助

Jest v29.5.0升级后Redux Reselect选择器Mock失效问题

问题描述

在Jest v27中,通过全局文件Mock所有Redux Reselect选择器的方案运行正常,但升级至Jest v29.5.0后完全失效。

全局Mock选择器的代码如下:

jest.mock('redux/mainData/selectors', () => ({
  selectLoading: jest.fn(() => false),
  selectData: jest.fn(() => [{ id: '1' }]),
}));

jest.setup.ts中保留的useSelector配置:

jest.mock('react-redux', () => ({
  useSelector: jest.fn(fn => fn()),
}));

测试包含以下代码的组件时:

const data = useSelector(selectData);

执行data?.map(...)会抛出错误:

Error: Uncaught [TypeError: Cannot read properties of undefined (reading 'data')]

Mock文件包含约300个选择器,导致所有测试失败。尝试过以下两种Mock方式均无效:

方式1:

jest.mock('redux/mainData/selectors', () => ({
  selectData: () => ([{ id: '1' }]),
}));

方式2:

jest.mock('redux/mainData/selectors', () => ({
  selectData: jest.fn().mockReturnValueOnce([{}]);
}));

实际选择器代码:

export const selectData = createSelector(
  selectMainData,
  ({data}) => data,
);

当前环境:Jest v29.5.0、Reselect v4.1.8

解决方案

方案1:调整useSelector的Mock实现

原useSelector Mock直接调用selector函数但未传入state参数,若选择器Mock未生效则会执行原始代码并报错。修改为传递模拟的state,确保原始选择器能正常返回值:

jest.mock('react-redux', () => ({
  useSelector: jest.fn((selector) => selector({
    // 根据你的Redux state结构填充模拟数据
    mainData: { data: [{ id: '1' }] }
  })),
}));

此方案无需单独Mock每个选择器,适合选择器数量较多的场景。

方案2:确保选择器Mock完全覆盖原始模块

  1. 检查jest.config.js中是否将jest.setup.ts配置在setupFilesAfterEnv中(而非setupFiles),确保Mock在测试框架初始化后执行:
module.exports = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
  // 其他配置...
};
  1. 确保全局选择器Mock完整覆盖所有导出的选择器,示例:
jest.mock('redux/mainData/selectors', () => ({
  // 逐个Mock所有300个选择器
  selectLoading: jest.fn(() => false),
  selectData: jest.fn(() => [{ id: '1' }]),
  // 其他选择器的Mock...
}));

方案3:Mock Reselect的createSelector

直接MockcreateSelector,让它返回最终的转换函数,配合useSelector传入的模拟state使用:

// 在jest.setup.ts中添加
jest.mock('reselect', () => ({
  createSelector: (...args) => args[args.length - 1],
}));

// 同时调整useSelector的Mock
jest.mock('react-redux', () => ({
  useSelector: jest.fn((selector) => selector({
    mainData: { data: [{ id: '1' }] }
  })),
}));

此方案无需Mock每个选择器,通过让选择器直接读取模拟state返回结果。

内容的提问来源于stack exchange,提问作者marcus-linmarkson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 11:08:21