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

如何使用Jest测试静态工厂方法内部创建的实例的方法调用?

测试工厂方法内实例方法调用的两种常用方案

方案1:spy类原型上的目标方法

所有实例的公有方法都继承自类原型,你可以在调用工厂方法前,提前在原型上挂载spy,后续工厂内创建的实例调用对应方法时会被spy捕获,适合绝大多数简单测试场景。

以Jest测试框架为例,测试代码如下:

import { MyClass } from './your-class-file'
import { DomainEvent } from './your-event-file'

test('create工厂满足条件时应调用目标方法', () => {
  // 提前在原型上spy要测试的方法,示例为原代码中的apply,可替换为你要测试的doSomething
  const targetMethodSpy = jest.spyOn(MyClass.prototype, 'apply').mockImplementation(jest.fn())

  // 调用工厂方法
  const instance = MyClass.create(true)

  // 断言方法被正确调用
  expect(targetMethodSpy).toHaveBeenCalledTimes(1)
  expect(targetMethodSpy).toHaveBeenCalledWith(expect.any(DomainEvent))

  // 测试完成后恢复原方法,避免影响其他用例
  targetMethodSpy.mockRestore()
})

方案2:mock类构造函数,返回提前注入spy的自定义实例

如果你不想污染类原型,或者需要自定义实例的其他属性/方法,可以直接mock类的构造逻辑,让工厂方法内new MyClass()时返回你提前创建好的、已经挂载了spy的实例。

示例代码:

import * as MyClassModule from './your-class-file'
import { DomainEvent } from './your-event-file'

test('create工厂满足条件时应调用目标方法', () => {
  // 提前创建实例并挂载spy
  const mockInstance = new MyClassModule.MyClass()
  const targetMethodSpy = jest.spyOn(mockInstance, 'apply').mockImplementation(jest.fn())

  // mock类的构造函数,所有new操作都返回我们提前准备的实例
  const classSpy = jest.spyOn(MyClassModule, 'MyClass').mockReturnValue(mockInstance)

  // 调用工厂方法
  const result = MyClassModule.MyClass.create(true)

  // 断言
  expect(targetMethodSpy).toHaveBeenCalledTimes(1)
  expect(targetMethodSpy).toHaveBeenCalledWith(expect.any(DomainEvent))

  // 恢复mock
  classSpy.mockRestore()
  targetMethodSpy.mockRestore()
})

注意事项

  • 若你要测试的是私有方法,不建议直接spy,优先测试方法调用产生的公有可观测副作用即可,确实需要测试的话可以先把方法调整为protected权限。
  • 其他测试框架(如Vitest)的逻辑完全一致,替换对应spy/mock的API即可。

内容的提问来源于stack exchange,提问作者Ngọc Nguyễn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 14:45:03