Vitest无法Mock被测文件内函数问题求助
同一个模块内Vitest Mock函数不生效的问题解决
你遇到的是同模块内函数无法被Vitest Mock的典型问题,核心原因是模块内部函数调用的是本地引用,而非导出的引用。
问题根源
在test.ts中,foo直接调用的是模块内部的bar变量,不是你通过import * as testFile拿到的导出对象上的bar。vi.spyOn只能mock导出对象上的方法,但foo根本没用到这个导出的引用,所以mock不会生效。
解决方案
方案1:让模块内部通过自身导出调用函数
修改test.ts,让foo通过模块自身的导出引用调用bar,这样mock导出的bar就能影响到foo:
// test.ts export const bar = () => 'bar' // 引入自身模块的导出 import * as self from './test' export const foo = () => `I am foo. bar is ${self.bar()}`
测试代码无需修改,即可正常生效。
方案2:拆分模块(已验证有效)
将bar移到单独模块,彻底隔离依赖:
// utils.ts export const bar = () => 'bar'
// test.ts import { bar } from './utils' export const foo = () => `I am foo. bar is ${bar()}`
测试文件mock独立模块的bar:
import { describe, expect, it, vi } from 'vitest' import { foo } from './test' import * as utils from './utils' describe('module', () => { it('foo', () => { vi.spyOn(utils, 'bar').mockImplementation(() => 'fake bar') expect(foo()).toEqual('I am foo. bar is fake bar') }) })
方案3:使用Vitest模块Mock
无需修改原代码,直接mock整个模块的导出:
// test.unit.spec.ts import { describe, expect, it, vi } from 'vitest' // 先mock模块,再导入目标函数 vi.mock('./test', () => ({ // 自定义mock的bar bar: vi.fn(() => 'fake bar'), // 保留原foo的实现 ...vi.importActual('./test') })) import { foo, bar } from './test' describe('module', () => { it('foo', () => { expect(foo()).toEqual('I am foo. bar is fake bar') expect(bar).toHaveBeenCalled() }) })
内容的提问来源于stack exchange,提问作者Mr.Tr33
相关产品推荐
相关产品推荐

