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

如何使用Jest模拟React.useContext进行组件单元测试?

如何在单元测试中自定义全局上下文值

问题背景

我正在为一个依赖全局上下文的组件编写单元测试,组件中获取上下文的代码如下:

import { globalContext } from "../../globalContext";
const { rowId, num, activeNum } = useContext(globalContext);

需要在测试中自由设置这些上下文值,以下是两种常用实现方案:


方案一:直接模拟useContext钩子(Jest + React Testing Library)

通过Jest的mock功能重写useContext,让它返回你预设的上下文值,适合快速隔离依赖的简单场景。

示例代码:

import { render, screen } from '@testing-library/react';
import { useContext } from 'react';
import YourComponent from './YourComponent';
import { globalContext } from '../../globalContext';

// 保留React其他原有功能,仅mock useContext
jest.mock('react', () => ({
  ...jest.requireActual('react'),
  useContext: jest.fn(),
}));

describe('目标组件测试', () => {
  it('使用自定义上下文值渲染', () => {
    // 定义需要的上下文数据
    const mockContext = {
      rowId: 'test-row-001',
      num: 3,
      activeNum: 1,
    };

    // 让useContext调用时返回mock数据
    (useContext as jest.Mock).mockReturnValue(mockContext);

    render(<YourComponent />);

    // 根据组件渲染内容编写断言,比如检查rowId是否展示
    expect(screen.getByText('test-row-001')).toBeInTheDocument();
  });
});

方案二:用上下文提供者包裹组件(推荐)

不mock钩子,而是在测试中使用globalContext.Provider直接包裹组件,传入自定义值,这种方式更贴近组件真实运行逻辑,测试结果更可靠。

示例代码:

import { render, screen } from '@testing-library/react';
import YourComponent from './YourComponent';
import { globalContext } from '../../globalContext';

describe('目标组件测试', () => {
  it('使用自定义上下文值渲染', () => {
    const mockContext = {
      rowId: 'test-row-002',
      num: 8,
      activeNum: 5,
    };

    render(
      <globalContext.Provider value={mockContext}>
        <YourComponent />
      </globalContext.Provider>
    );

    // 断言组件正确使用上下文数据
    expect(screen.getByText('test-row-002')).toBeInTheDocument();
  });
});

方案选择建议

  • 若组件逻辑简单、仅需隔离上下文依赖,选方案一;
  • 若组件依赖上下文的更新逻辑或需要更真实的渲染环境,优先选方案二。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 12:56:00