使用Jest测试NextJS+Redux-Toolkit组件时出现初始化前访问错误
解决Jest测试NextJS+Redux-Toolkit组件时出现的
ReferenceError: Cannot access '_default' before initialization错误 这个错误通常由模块初始化顺序问题或循环依赖触发,结合你的代码场景,主要有以下几个核心问题点及对应解决方案:
问题1:自定义render的参数默认值过早执行
你的自定义render工具中,initialState = {...store.getState()}作为参数默认值,会在模块导入阶段就执行,而非函数调用时。此时store可能还未完成初始化(尤其是Redux Persist的异步逻辑),进而触发引用错误。
修复代码:
import React from 'react'; import { render as rtlRender } from '@testing-library/react'; import { Provider } from 'react-redux'; import { store } from '../../@core/state/store' import type { RootState } from '../../@core/state/store'; const render = ( ui: any, { initialState, ...renderOptions }: { initialState?: RootState } = {} ) => { // 将initialState默认值移到函数内部,确保store初始化完成后再求值 const actualInitialState = initialState ?? { ...store.getState() }; const Wrapper = ({ children }: any) => ( <Provider store={store}>{children}</Provider> ); return rtlRender(ui, { wrapper: Wrapper, ...renderOptions}); }; export * from '@testing-library/react'; export { render};
问题2:Redux Persist在测试环境的兼容性问题
Jest默认没有真实的localStorage环境,Redux Persist的初始化逻辑会干扰store创建,导致初始化顺序异常。
修复代码(按环境切换store配置):
import { persistStore, persistReducer, FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER } from 'redux-persist' import storage from "redux-persist/lib/storage"; import reducers from "./reducers"; import { configureStore } from "@reduxjs/toolkit"; let store; if (process.env.NODE_ENV === 'test') { // 测试环境跳过persist逻辑,直接使用原始reducer store = configureStore({ reducer: reducers, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false, // 测试环境可关闭序列化检查简化配置 }), }); } else { const persistConfig = { key: 'my-store', storage }; const persistedReducer = persistReducer(persistConfig, reducers); store = configureStore({ reducer: persistedReducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: { ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER], }, }), }); } export { store }; export type RootState = ReturnType<typeof store.getState>; export type AppDispatch = typeof store.dispatch; // 仅在非测试环境导出persistor export const persistor = process.env.NODE_ENV !== 'test' ? persistStore(store) : undefined;
问题3:复用生产store导致的测试污染与初始化问题
直接复用生产store会造成测试间状态污染,也更容易触发初始化顺序问题,推荐使用测试专用的独立store。
修复代码(自定义render中创建独立测试store):
import React from 'react'; import { render as rtlRender } from '@testing-library/react'; import { Provider } from 'react-redux'; import { configureStore } from '@reduxjs/toolkit'; import reducers from '../../@core/state/reducers'; import type { RootState } from '../../@core/state/store'; const render = ( ui: any, { initialState, ...renderOptions }: { initialState?: Partial<RootState> } = {} ) => { // 每次测试创建全新store,避免状态污染 const store = configureStore({ reducer: reducers, preloadedState: initialState, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false, }), }); const Wrapper = ({ children }: any) => ( <Provider store={store}>{children}</Provider> ); return rtlRender(ui, { wrapper: Wrapper, ...renderOptions}); }; export * from '@testing-library/react'; export { render};
额外检查点
- 确认
AuthSlice中的initialState没有依赖未初始化的模块(比如是否引用了store或其他未加载的变量)。 - 检查
reducers/index.ts是否存在循环依赖(如reducers文件导入store,而store又导入reducers)。
内容的提问来源于stack exchange,提问作者Ghost Worker
相关产品推荐
相关产品推荐

