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

React组件测试:如何用Enzyme和Jest模拟工具函数返回值

使用Enzyme和Jest模拟外部工具函数测试React组件

刚好我之前也遇到过类似的场景,用Enzyme+Jest完全可以搞定,给你两种常用的实现方式,都是针对你这种在组件初始化时调用外部工具函数的情况:

方法一:使用jest.mock直接模拟整个工具模块

这种方式适合只需要模拟模块中特定函数的场景,直接在测试文件中mock整个utils模块,指定目标函数的mock实现:

// MyComponent.test.js
import React from 'react';
import { shallow } from 'enzyme';
import { MyComponent } from './MyComponent';
import { getCalculatedValue } from '../utils';

// 提前模拟整个utils模块,将getCalculatedValue替换为jest mock函数
jest.mock('../utils', () => ({
  getCalculatedValue: jest.fn()
}));

describe('MyComponent', () => {
  it('should initialize with the mocked calculated value', () => {
    // 给mock函数设置想要的返回值
    const mockCalculatedValue = 100;
    getCalculatedValue.mockReturnValue(mockCalculatedValue);

    // 渲染组件(此时constructor会调用mock后的函数)
    const wrapper = shallow(<MyComponent />);

    // 验证函数被调用
    expect(getCalculatedValue).toHaveBeenCalledTimes(1);
    // 根据你的组件逻辑写断言,比如如果值存在state里:
    expect(wrapper.state('calculatedValue')).toBe(mockCalculatedValue);
  });

  it('should handle different mocked values in separate tests', () => {
    // 每个测试可以设置不同的返回值
    getCalculatedValue.mockReturnValue(200);
    const wrapper = shallow(<MyComponent />);
    
    expect(wrapper.state('calculatedValue')).toBe(200);
  });
});

方法二:使用jest.spyOn单独模拟目标函数

如果你不想mock整个模块,只想替换单个函数的实现,可以用jest.spyOn,这种方式更灵活,也方便在测试后恢复原函数:

// MyComponent.test.js
import React from 'react';
import { shallow } from 'enzyme';
import { MyComponent } from './MyComponent';
import * as utils from '../utils';

describe('MyComponent', () => {
  let getCalculatedValueSpy;

  // 每个测试前创建spy,替换原函数
  beforeEach(() => {
    getCalculatedValueSpy = jest.spyOn(utils, 'getCalculatedValue');
  });

  // 每个测试后恢复原函数,避免影响其他测试
  afterEach(() => {
    getCalculatedValueSpy.mockRestore();
  });

  it('should use the mocked value from spy during initialization', () => {
    const mockVal = 50;
    getCalculatedValueSpy.mockReturnValue(mockVal);

    const wrapper = shallow(<MyComponent />);

    expect(getCalculatedValueSpy).toHaveBeenCalled();
    // 同样根据组件实际逻辑断言
    expect(wrapper.state('calculatedValue')).toBe(mockVal);
  });
});

关键注意点

因为getCalculatedValue是在组件的constructor中调用的,所以必须在渲染组件之前设置好mock的返回值,否则组件初始化时会拿到mock函数的默认返回(通常是undefined),导致测试不符合预期。

另外,断言部分要根据你的组件实际逻辑调整——如果组件把计算值渲染到DOM中,就用wrapper.find('.some-class').text()这类方式验证;如果存在props或其他状态里,就对应断言即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:06:57