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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 01:20:19