Jest测试React Native FlatList组件报setExtraStackFrame非函数错误
问题结论
这个是jest-expo与React/React Native版本不匹配导致的已知兼容性问题,不是业务代码的逻辑错误。
报错原因
该错误通常触发于React 18+版本与旧版测试依赖搭配的场景:React 18移除了内部API ReactDebugCurrentFrame.setExtraStackFrame,而FlatList依赖的CellRenderer组件的测试渲染逻辑仍在调用该API,因此抛出类型错误。
可行解决思路
- 方案1:对齐依赖版本
确保jest-expo版本与你的Expo SDK版本完全一致,执行npx expo install jest-expo即可让Expo自动安装匹配的版本,避免手动安装时的版本不匹配问题。 - 方案2:补充缺失API的mock
在Jest的全局初始化文件(通常为jest-setup.js)中加入以下代码,给不存在的方法添加空实现:
// 两种导入路径二选一即可 import * as ReactDebugCurrentFrame from 'react-reconciler/src/ReactDebugCurrentFrame'; ReactDebugCurrentFrame.setExtraStackFrame = () => {}; // 或全局mock ReactNativeRenderer jest.mock('react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev', () => { const actual = jest.requireActual('react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev'); actual.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactDebugCurrentFrame.setExtraStackFrame = () => {}; return actual; });
- 方案3:Mock FlatList绕过底层依赖
如果仅需测试业务逻辑不需要验证FlatList本身的行为,可以直接在Jest配置中Mock FlatList组件,简化测试逻辑同时规避兼容性问题:
在项目根目录的__mocks__/react-native.js文件中添加:
const actualRN = jest.requireActual('react-native'); module.exports = { ...actualRN, FlatList: jest.fn(({ data = [], renderItem }) => ( <>{data.map((item, index) => renderItem({ item, index, key: index }))}</> )) };
额外代码修正
你的测试代码存在一个低级错误:自定义的
render函数和从测试库导入的render方法重名,会触发无限递归调用。你需要修改自定义函数的名称,比如改为renderMessageStack,或者给导入的测试库render方法设置别名import { render as rtlRender } from '@testing-library/react-native',在自定义函数中调用rtlRender即可。
内容的提问来源于stack exchange,提问作者Richard Bosworth
相关产品推荐
相关产品推荐

