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

如何使用Jest Mock方法内部创建的DataHandler类?

如何正确Mock Jest中内部实例化的DataHandler类

我在测试ProductDatatHandler类的process方法时,遇到了无法Mock内部创建的DataHandler实例的问题,报错「TypeError: DataHandler is not a constructor」。原代码中process方法会通过LookupService获取处理器,然后实例化DataHandler并调用其insert方法。

原Mock代码错误在于没有正确模拟DataHandler这个类的构造函数,而是直接导出了insert方法,导致代码执行new DataHandler()时失败。


正确的Mock写法

要正确Mock内部实例化的类,需要让Jest模拟整个模块,导出一个Mock构造函数,并且该构造函数返回的实例包含Mock的insert方法:

jest.mock('./product-handlers/data-handler', () => {
  // 定义Mock的insert方法
  const mockInsert = jest.fn();

  return {
    __esModule: true,
    // 导出Mock的DataHandler构造函数,实例化时返回带有insert方法的对象
    DataHandler: jest.fn().mockImplementation(() => ({
      insert: mockInsert
    }))
  };
});

测试中的验证逻辑

在测试用例中,你可以导入Mock后的DataHandler,并验证它的实例化和方法调用情况:

import { DataHandler } from './product-handlers/data-handler';
import { ProductDatatHandler } from './product-data-handler';
import { LookupService } from './service/lookup';

// 类型断言,将DataHandler转为Jest Mock类型
const MockDataHandler = DataHandler as jest.Mock;

describe('ProductDatatHandler', () => {
  let productHandler: ProductDatatHandler;
  let mockLookupService: jest.Mocked<LookupService>;

  beforeEach(() => {
    // 每次测试前重置Mock状态
    MockDataHandler.mockClear();
    const mockInsert = MockDataHandler.mock.results[0]?.value?.insert;
    if (mockInsert) mockInsert.mockClear();

    // 模拟LookupService的返回值
    mockLookupService = {
      getProductHandlerForType: jest.fn().mockResolvedValue({})
    };
    productHandler = new ProductDatatHandler();
  });

  it('实例化DataHandler并调用insert方法(当data存在value时)', async () => {
    const testData = {
      type: 'test-type',
      value: 'test-value'
    } as ProductMetadata;

    await productHandler.process(testData, mockLookupService);

    // 验证DataHandler被正确实例化,且传入了处理器参数
    expect(MockDataHandler).toHaveBeenCalledWith(expect.any(Object));
    // 验证insert方法被调用,且传入了测试数据
    const mockInsert = MockDataHandler.mock.results[0].value.insert;
    expect(mockInsert).toHaveBeenCalledWith(testData);
  });
});

错误原因说明

你之前的Mock代码直接导出了insert方法,但原代码中是通过new DataHandler()来创建实例的——此时模块导出的DataHandler应该是一个构造函数,而不是普通方法。之前的写法导致Jest替换后的DataHandler不是构造函数,所以执行new操作时抛出类型错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 22:05:15