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

Jest中对ESM模块命名导出进行Stub的标准方法是什么?

ESM模块命名导出的Spy/Mock问题与解决方案

这个问题并非仅针对Jest,所有具备Stub功能的测试库都会遇到。

ESM模块的命名导出与默认导出是不可变的,这意味着以下写法会触发运行时错误:

// @filename foo.mjs
export function foo() { ... }

// @filename foo.test.mjs
import * as foo from './foo.mjs'
// 触发运行时错误:命名导出"foo"是不可变的
jest.spyOn(foo, 'foo')

问题

当前对ESM模块的命名导出进行Spy/Mock的标准方式是什么?


潜在解决方案

委托给可变对象

将实际业务逻辑放在可变对象中,对外导出的函数仅做转发,以此实现对目标逻辑的Spy/Mock:

// @filename foo.mjs
export function foo() {
  return _private.foo()
}
export const _private = {
  foo: () => { ... }
}

// @filename foo.test.mjs
import { _private } from './foo.mjs'
jest.spyOn(_private, 'foo')

用代理包装函数

通过自定义代理函数包裹目标函数,将实际逻辑挂载到代理对象的可变属性上,测试时针对该属性进行Spy/Mock:

// @filename proxy.mjs
export function proxy(fn) {
  const functionProxy = function (...args) {
    return functionProxy._original(...args)
  }
  functionProxy._original = fn
  return functionProxy
}

// @filename foo.mjs
import { proxy } from './proxy.mjs'
export const foo = proxy(() => { ... })

// @filename foo.test.mjs
import { foo } from './foo.mjs'
jest.spyOn(foo, '_original')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 20:48:46