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

如何使用Jest和Enzyme模拟React组件中的函数

如何用Jest和Enzyme测试React函数组件内部的func函数

你好呀!针对你在React函数组件中测试内部func函数的需求,我来一步步给你讲清楚怎么实现~

首先先看你的原始组件代码(我稍微调整了格式让它更规范):

import { useState } from 'react';

const App = () => {
  const [state, setState] = useState("");
  
  const func = (item) => {
    setState(item);
  };
  
  return (
    <div>{state}</div>
  );
};

export default App;

你的测试代码已经写了一部分,但因为func是组件内部的函数(函数组件没有实例,没法直接通过wrapper.instance()获取),所以需要用下面两种方式来处理:


方式一:修改组件暴露内部函数(推荐用于直接测试函数逻辑)

如果想直接调用func并验证它的效果,我们可以用forwardRef和useImperativeHandle把内部函数暴露给测试代码:

第一步:更新组件代码

import { useState, forwardRef, useImperativeHandle } from 'react';

// 用forwardRef包裹组件
const App = forwardRef((props, ref) => {
  const [state, setState] = useState("");
  
  const func = (item) => {
    setState(item);
  };
  
  // 把func暴露给外部的ref
  useImperativeHandle(ref, () => ({
    func
  }));
  
  return (
    <div>{state}</div>
  );
});

export default App;

第二步:编写测试代码

import { mount } from 'enzyme';
import App from './App';
import React from 'react';

test("测试func函数能正确更新state", () => {
  // 创建一个ref来获取组件暴露的方法
  const appRef = React.createRef();
  const wrapper = mount(<App ref={appRef} />);
  const testItem = "test";
  
  // 直接调用内部的func函数
  appRef.current.func(testItem);
  
  // 验证页面上的state是否更新为testItem
  expect(wrapper.text()).toBe(testItem);
});

方式二:模拟useState间接测试(无需修改组件)

如果不想改动组件代码,可以通过模拟React的useState来间接验证func是否正确调用了setState:

测试代码示例

import { mount } from 'enzyme';
import App from './App';
import React from 'react';

test("测试func函数会调用setState", () => {
  // 模拟setState函数,用来追踪调用情况
  const mockSetState = jest.fn();
  // 替换React.useState的实现,返回初始值和我们的mock函数
  jest.spyOn(React, 'useState').mockImplementation(() => ["", mockSetState]);
  
  const wrapper = mount(<App />);
  
  // 注意:这种方式下我们没法直接调用func,所以需要给组件添加触发func的交互元素(比如按钮)
  // 假设你给组件加了一个点击后调用func的按钮:<button onClick={() => func("test")}>更新</button>
  wrapper.find('button').simulate('click');
  
  // 验证mockSetState是否被正确调用,参数是"test"
  expect(mockSetState).toHaveBeenCalledWith("test");
  
  // 别忘了恢复useState的原始实现,避免影响其他测试
  React.useState.mockRestore();
});

补充说明

  • 如果你的func有更复杂的逻辑(比如处理数据再调用setState),方式一可以更直接地测试函数的输入输出;
  • 方式二更适合测试函数的副作用(比如是否正确调用了setState),不需要改动原有组件结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 15:17:59