Vitest依赖模拟异常:函数未被调用的问题排查
问题根源与解决方案
你的问题出在ES模块命名导出的模拟未正确标记模块类型,导致被测文件中解构导入的t没有绑定到模拟函数,而是调用了真实的intlify翻译函数。
原因解析
当使用vi.mock模拟ES模块的命名导出时,需要明确标记模拟对象为ES模块(添加__esModule: true)。如果缺少这个标记,Vitest会将模拟模块当作CommonJS模块处理,此时直接解构导入的成员(如import { t } from '@/helpers')无法正确关联到模拟的函数,而是继续引用原始模块的导出。
而改用import * as helpers from '@/helpers'的方式时,你是直接访问模拟模块对象的属性,不受模块类型标记的影响,因此能正常调用模拟函数。
修复后的测试代码
修改@/helpers的模拟逻辑,添加__esModule: true:
import { describe, it, expect, vi, afterEach } from 'vitest'; import { useTitle } from '@vueuse/core'; import { setTitle } from './title'; import { t } from '@/helpers'; vi.mock('@vueuse/core', () => ({ __esModule: true, // 同样建议给@vueuse/core的模拟加上该标记 useTitle: vi.fn(), })); vi.mock('@/helpers', () => ({ __esModule: true, t: vi.fn(), })); describe('helpers: title', () => { afterEach(() => { vi.resetAllMocks(); }); describe('set title', () => { it('will set the title of the page', () => { t.mockImplementation(() => 'test'); setTitle('test'); expect(t).toHaveBeenCalledWith('test'); expect(useTitle).toHaveBeenCalledWith('test', expect.any(Object)); }); }); });
额外验证
修复后,被测文件setTitle函数中打印的t会显示为Vitest的模拟函数(而非真实的intlify函数),测试断言会正常通过,同时不会再出现[intlify] Not found 'test' key的错误。
内容的提问来源于stack exchange,提问作者nzmattman
相关产品推荐
相关产品推荐

