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

如何在Jest+React Testing Library中访问与修改React Context?

问题排查与修复方案

我帮你梳理下核心问题:你的Context配置和测试代码里都存在关键错误,导致组件无法感知loading状态的变化。下面一步步拆解修复:

1. 先修正生产环境的Provider配置错误

你在index.js里给ThemesProvider手动传了空的value={{}},这会直接覆盖Provider内部生成的所有上下文值(包括loading、fetchThemes等方法),这是最致命的问题!

错误代码:

import { ThemesProvider } from "./context/ThemeProvider";
ReactDOM.render(
  <ThemesProvider value={{}}>
    <App />
  </ThemesProvider>,
  document.getElementById("root")
);

修复后:

删掉手动传入的value,因为ThemesProvider内部已经帮你维护好了完整的上下文状态:

import { ThemesProvider } from "./context/ThemeProvider";
ReactDOM.render(
  <ThemesProvider>
    <App />
  </ThemesProvider>,
  document.getElementById("root")
);

2. 测试代码的3个关键错误修复

错误1:直接从Context对象解构loading

你写的const { loading } = AvailableThemesContext;完全无效——AvailableThemesContext是用React.createContext()创建的上下文容器,本身不存储状态,必须通过useContext(AvailableThemesContext)或者Consumer才能获取到Provider内部的状态。直接删掉这行代码即可。

错误2:使用了错误的Provider名称

测试里写的<ThemeProvider value={{ loading: false}}>少了个s,你的Provider导出的是ThemesProvider,名称不匹配会导致组件根本没被正确的上下文包裹。

错误3:未正确用Provider包裹测试组件

修复后的测试代码应该用正确的ThemesProvider包裹组件,并传入需要模拟的状态:

import React from "react";
import { render, screen } from "./test-utils";
import CalendarView from "../views/CalendarView";
import { ThemesProvider } from "../context/ThemeProvider"; // 导入正确的Provider

describe("<CalendarView />", () => {
  test("渲染加载器当loading为true时", async () => {
    render(
      <ThemesProvider value={{ loading: true, contextTheme: {} }}>
        <CalendarView />
      </ThemesProvider>
    );
    expect(screen.getByLabelText("audio-loading")).toBeInTheDocument();
  });

  test("渲染选择器组件当loading为false时", () => {
    render(
      <ThemesProvider value={{ loading: false, contextTheme: {} }}>
        <CalendarView />
      </ThemesProvider>
    );
    expect(screen.getByTestId("picker-component")).toBeInTheDocument();
  });
});

如果你的test-utils里有自定义的render方法支持上下文覆盖,也可以简化成:

test("渲染选择器组件当loading为false时", () => {
  render(<CalendarView />, {
    context: {
      AvailableThemesContext: { loading: false, contextTheme: {} }
    }
  });
  expect(screen.getByTestId("picker-component")).toBeInTheDocument();
});

3. 额外优化:给Context设置默认值

为了避免组件在未被Provider包裹时崩溃,建议创建Context时设置默认值:

const AvailableThemesContext = React.createContext({
  contextTheme: {},
  loading: true,
  fetchThemes: () => {},
  refresh: () => {},
  setLoading: () => {},
});

最后再确认下你的CalendarView组件是否正确通过useContext获取状态:

import { useContext } from "react";
import AvailableThemesContext from "../context/ThemeProvider";

const CalendarView = () => {
  const { loading } = useContext(AvailableThemesContext);

  if (loading) {
    return <div aria-label="audio-loading">加载中...</div>;
  }

  return <div data-testid="picker-component">选择器组件</div>;
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 06:22:48