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

使用Jest与Provider组件在React测试中无法注入MobX Store

问题描述

我在为React组件编写单元测试时,需要将MobX Store的某个属性设置为非默认状态。尝试修改状态后通过<Provider>注入组件,但测试中该属性值始终为false,各种模拟/替换Store的方法都没生效。

Store代码

export class ModalControlStore {
     root: RootStore;

    constructor(root: RootStore) {
        this.root = root;
        makeAutoObservable(this);
    }

    modalIsOpen = false;

    setModalIsOpen(isModalOpen: boolean) {
        this.modalIsOpen = modalIsOpen
    }
}

组件中获取Store的代码

export function useModalControlStore() {
  const { modalControlStore  } = useRootStore();
  return modalControlStore ;
}

组件中使用Store的方式

const { modalIsOpen } = useModalControlStore();

当前测试代码

beforeEach(() => {
    const modalControlStore = useModalControlStore();
    modalControlStore.setModalIsOpen(true);

    render(
        <Provider modalControlStore={modalControlStore}>
           <PopUpModal/>
        </Provider>
    )
});

解决方案

你的测试代码存在两个核心问题:

  1. 在渲染组件前直接调用useModalControlStore()违规:React Hooks只能在组件或自定义Hook内部调用,测试环境中直接调用会脱离Provider上下文,拿到的不是你要注入的目标Store实例。
  2. 未正确创建并注入自定义Store实例:需要手动创建ModalControlStore实例(可模拟RootStore依赖),修改状态后再通过Provider注入组件。

修改后的测试代码示例(单Store注入)

// 模拟RootStore(按需补充实际依赖)
const mockRootStore = {} as RootStore;

beforeEach(() => {
    // 手动创建Store实例
    const modalControlStore = new ModalControlStore(mockRootStore);
    // 设置目标状态
    modalControlStore.setModalIsOpen(true);

    render(
        <Provider modalControlStore={modalControlStore}>
           <PopUpModal/>
        </Provider>
    )
});

若依赖RootStore全局注入

如果你的useRootStore是从全局RootStore Provider中获取实例,需注入完整的模拟RootStore:

// 模拟包含目标Store的RootStore
const mockRootStore = {
    modalControlStore: new ModalControlStore({} as RootStore)
} as RootStore;

// 提前设置状态
mockRootStore.modalControlStore.setModalIsOpen(true);

beforeEach(() => {
    render(
        <Provider rootStore={mockRootStore}>
           <PopUpModal/>
        </Provider>
    )
});

简化方案:直接Mock Hook

若使用Jest,可直接MockuseModalControlStore,返回预设状态的Store:

jest.mock('./path-to-useModalControlStore', () => ({
    useModalControlStore: () => ({
        modalIsOpen: true,
        setModalIsOpen: jest.fn()
    })
}));

beforeEach(() => {
    render(<PopUpModal/>);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 18:43:25