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

如何使用Jest仅Mock Context Provider中的单个状态变量?

问题根源

你当前测试直接传入静态的emptyApi和修改后的defaultState作为Context值,emptyApi内的setStep是预先定义的空函数,没有绑定真实React状态,调用后自然不会触发状态更新,相当于完全抛弃了原Provider的内部逻辑。

解决方案

这里提供两种常用实现方式,都可以做到只mock userList 保留step相关逻辑:

方案1:复用原AppContextProvider,仅mock用户接口

该方式最贴近应用真实运行逻辑,所有原有状态逻辑100%保留,仅需要把获取用户的接口返回替换为mock数据即可:

import Progress from './progress'
import { AppContextProvider } from './context/AppContext'
import { render, screen } from "@testing-library/react"

// 示例:假设你获取用户列表调用的是axios.get('/api/users'),直接mock该请求
jest.mock('axios', () => ({
  ...jest.requireActual('axios'),
  get: jest.fn((url) => {
    if (url === '/api/users') {
      // 返回你需要的mock用户列表
      return Promise.resolve({ data: [{id: 1, name: '测试用户1'}, {id: 2, name: '测试用户2'}] })
    }
    return jest.requireActual('axios').get(url)
  })
}))

describe('progress', () => {
  it('should go through the steps', async () => {
    render(
      // 直接使用原有的AppContextProvider,不要自定义传入静态value
      <AppContextProvider>
        <Progress />
      </AppContextProvider>
    )

    // 若组件初始化会调用callUsers,可等待接口返回完成再执行后续操作
    // 此时step相关逻辑完全正常,调用setStep会真实更新状态触发重渲染
  })
})

方案2:自定义测试专用Provider,直接传入mock用户列表

如果你不想mock接口,想要直接指定userList的值,可以写一个测试专用Provider,完全复用原Provider的step逻辑,仅把userList替换为你传入的固定值:

import Progress from './progress'
import AppContext from './context/AppContext'
import { render, screen } from "@testing-library/react"

// 测试用自定义Provider,保留原step逻辑,支持传入mock用户列表
const TestAppContextProvider = ({ children, mockUserList = [] }) => {
  // 原Provider的step逻辑完全保留
  const [stepNum, setStepNum] = React.useState(0);

  const api = {
    setStep: setStepNum,
    callUsers: () => {} // 不需要调用接口可留空,需要的话也可以保留原逻辑
  }

  const state = {
    userList: mockUserList, // 直接使用传入的mock数据
    step: stepNum,
  }

  return <AppContext.Provider value={{ api, state }}>{children}</AppContext.Provider>
}

describe('progress', () => {
  it('should go through the steps', () => {
    render(
      <TestAppContextProvider mockUserList={[{id: 1, name: '测试用户'}]}>
        <Progress />
      </TestAppContextProvider>
    )

    // 此时setStep调用会正常更新step状态,userList为你传入的mock值
  })
})

注意

你代码中的React组件名progress为小写,React会将其识别为原生HTML标签,建议改为大写开头的Progress避免异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 15:39:00