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
相关产品推荐
相关产品推荐

