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

测试React+Redux的Header组件时找不到react-redux上下文报错如何解决

问题原因

你的Header组件使用了react-redux的useSelector Hook,该Hook依赖Redux上下文环境,测试时直接渲染Header没有在外层包裹Redux的Provider组件,因此触发上下文找不到的报错。

解决方案

方案1:直接修改当前测试用例

步骤1:安装测试依赖(未安装时执行)

npm install redux-mock-store --save-dev

步骤2:修改Header.test.js代码

import { render, screen } from "@testing-library/react";
import { Provider } from "react-redux";
import configureMockStore from "redux-mock-store";
import Header from "../Header";

// 初始化mock store
const mockStore = configureMockStore([]);
const mockedSetOpenForm = jest.fn();

test("should render number of invoices", () => {
  // 构造测试需要的state,这里设置invoices长度为5匹配你测试的文本
  const store = mockStore({
    invoices: new Array(5).fill({})
  });
  // 渲染时用Provider包裹Header,传入模拟的store
  render(
    <Provider store={store}>
      <Header openForm={false} setOpenForm={mockedSetOpenForm} />
    </Provider>
  );
  const paragraphElement = screen.getByText(/There are 5 total invoices./i);
  expect(paragraphElement).toBeInTheDocument();
});

如果你的项目用的是Redux Toolkit,也可以直接用configureStore生成测试用的真实store:

import { configureStore } from "@reduxjs/toolkit";
import invoiceReducer from "你的reducer实际存储路径";

const store = configureStore({
  reducer: {
    invoices: invoiceReducer
  },
  preloadedState: {
    invoices: new Array(5).fill({})
  }
})

方案2:封装通用测试渲染工具(推荐)

如果项目里很多组件都用到Redux,可以封装一个自定义的render函数,避免每次测试都手动包Provider:

  1. 在测试目录新建test-utils.js:
import { render } from '@testing-library/react'
import { Provider } from 'react-redux'
import configureMockStore from 'redux-mock-store'

const mockStore = configureMockStore([])

const customRender = (ui, { preloadedState = {}, ...renderOptions } = {}) => {
  const store = mockStore(preloadedState)
  const Wrapper = ({ children }) => <Provider store={store}>{children}</Provider>
  return render(ui, { wrapper: Wrapper, ...renderOptions })
}

// 重新导出testing-library的所有方法,替换原来的render
export * from '@testing-library/react'
export { customRender as render }
  1. 之后测试Redux组件时直接引入这个自定义的render,传入需要的预加载state即可:
import { render, screen } from './test-utils'
import Header from "../Header";

const mockedSetOpenForm = jest.fn();

test("should render number of invoices", () => {
  render(<Header openForm={false} setOpenForm={mockedSetOpenForm} />, {
    preloadedState: {
      invoices: new Array(5).fill({})
    }
  });
  const paragraphElement = screen.getByText(/There are 5 total invoices./i);
  expect(paragraphElement).toBeInTheDocument();
});
额外注意点

Header组件中读取了localStorage的profile字段,如果后续测试涉及点击按钮等交互逻辑,需要提前模拟localStorage的值:

beforeEach(() => {
  Storage.prototype.getItem = jest.fn(() => JSON.stringify({ result: { name: '测试用户' } }))
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 02:15:04