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

React测试遇'store'只读错误,求用Redux Toolkit改写测试Store方案

问题:React测试中改用Redux Toolkit的configureStore及解决store只读错误

我是React测试新手,当前测试用createTestStore使用Redux原生createStore和combineReducers关联实际reducer,想了解如何改用Redux Toolkit的configureStore实现。原本期望reducer自动初始化正确初始状态,但在beforeEach中赋值store时出现“'store' is read-only”错误,寻求解决建议。

我的store.ts代码

// this is for testing
export function createTestStore() {
  const store = createStore(
    combineReducers({
      user: userReducer,
      config: configReducer,
    })
  );
  return store;
}

export const history: History = createBrowserHistory();

const rootReducer = (history: any) => ({
 router: connectRouter(history),
  app: appReducer,
  user: userReducer,
  config: configReducer,
});

const preloadedState = {};
export const store = configureStore({
 middleware: [thunk as ThunkMiddleware, routerMiddleware(history)],
 reducer: rootReducer(history) as any,
 preloadedState,
});
export type AppDispatch = typeof store.dispatch;
export const useAppDispatch = () => useDispatch<AppDispatch>();

我的测试代码

let store;
describe("a test", () => {
  beforeEach(() => {
    store = createTestStore();
  });
  test('Component with a full reducer flow', async () => {
    // Create a redux store
    const { findByText } = render(
      <Provider store={store}>
        <ComponentToTest />
      </Provider>
    );
    await findByText('This text is now visible because your state was updated by the reducer');
  });
});

解决方案

一、改用Redux Toolkit的configureStore实现测试用store

直接复用项目已有的rootReducer,用configureStore重构测试用store创建函数,同时适配测试环境的路由需求:

// 导入必要依赖
import { configureStore } from '@reduxjs/toolkit';
import { routerMiddleware } from 'connected-react-router';
import { createMemoryHistory } from 'history';

// 重构测试用store创建函数
export function createTestStore(preloadedState = {}) {
  // 用内存history替代浏览器history,适配测试环境
  const testHistory = createMemoryHistory();
  return configureStore({
    reducer: rootReducer(testHistory),
    middleware: (getDefaultMiddleware) => 
      getDefaultMiddleware().concat(routerMiddleware(testHistory)),
    preloadedState,
  });
}

这样做的优势:

  • 复用生产环境的rootReducer,保证测试与生产的状态结构完全一致
  • Redux Toolkit自动处理reducer初始化、中间件默认配置,无需手动调用combineReducers
  • 内存history避免测试依赖浏览器API,更稳定

二、解决“'store' is read-only”错误

错误根源是测试代码中声明的let store与store.ts中导出的export const store重名,导致变量被当作只读常量处理。只需修改测试代码中的变量名即可:

// 修改变量名,避免和全局导出的store冲突
let testStore;
describe("a test", () => {
  beforeEach(() => {
    testStore = createTestStore();
  });
  test('Component with a full reducer flow', async () => {
    const { findByText } = render(
      <Provider store={testStore}>
        <ComponentToTest />
      </Provider>
    );
    await findByText('This text is now visible because your state was updated by the reducer');
  });
});

内容的提问来源于stack exchange,提问作者walee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 06:05:18