Jest mocks置于辅助文件不运行,如何在辅助文件中mock fs.lstat
问题原因
- Jest 会自动将测试文件顶级作用域下的
jest.mock调用提升到所有import语句之前执行,保证模块导入前依赖就被mock。如果将jest.mock移到辅助文件的函数内部、或者导入辅助文件的时机晚于被测试模块的导入,就会导致被测试模块拿到原始的未被mock的fs引用,mock失效。
解决方法
方案1:直接封装固定mock逻辑到辅助文件
- 新建辅助文件
mockFs.ts:
/* mockFs.ts */ import * as fs from 'fs'; // 写在辅助文件顶级作用域的jest.mock仍会被提升到当前文件的导入前 jest.mock('fs'); const mockedFs = fs as jest.Mocked<typeof fs>; mockedFs.lstat.mockReturnValue(42);
- 测试文件调整导入顺序,必须先导入mock辅助文件,再导入被测试模块:
/* module.test.js */ // 先导入mock辅助文件 import './mockFs'; // 再导入被测试模块 import module from './module'; test('test', () => { expect(module()).toBe(42); });
方案2:封装可配置的复用mock函数
如果需要灵活调整mock返回值,可以将配置逻辑封装为导出函数:
- 辅助文件
mockFs.ts:
/* mockFs.ts */ import * as fs from 'fs'; jest.mock('fs'); const mockedFs = fs as jest.Mocked<typeof fs>; export function mockLstat(returnValue: unknown) { mockedFs.lstat.mockReturnValue(returnValue); }
- 测试文件使用:
/* module.test.js */ import { mockLstat } from './mockFs'; import module from './module'; // 自定义设置返回值 mockLstat(42); test('test', () => { expect(module()).toBe(42); });
方案3:全局生效mock
如果所有测试都需要mockfs.lstat,可以将mock逻辑写入jest全局启动文件:
- 在
jest.config.js中配置启动文件:
module.exports = { setupFilesAfterEnv: ['./jest.setup.js'] }
- 在
jest.setup.js中写入mock逻辑:
import * as fs from 'fs'; jest.mock('fs'); const mockedFs = fs as jest.Mocked<typeof fs>; mockedFs.lstat.mockReturnValue(42);
配置完成后所有测试文件无需额外导入即可直接使用该mock。
注意事项
- 不要将
jest.mock写在任何函数内部,仅顶级作用域下的jest.mock会被Jest自动提升 - 测试文件中必须保证mock相关逻辑的导入时机早于被测试模块的导入时机
内容的提问来源于stack exchange,提问作者user578895
相关产品推荐
相关产品推荐

