使用Jest测试真实文件系统返回空结果的问题如何解决?
问题原因
1. 核心问题:路径解析不一致
你遇到的空返回问题最核心的原因是不同运行环境下__dirname的指向不同:
- 手动运行TS代码(如ts-node)时,
__dirname指向.ts源码文件所在的实际目录,拼接后的模板路径是正确的 - Jest(配合ts-jest)运行时,TS文件会被编译到内存中,此时
__dirname指向内存中虚拟的编译后文件路径,你拼接的相对路径实际找不到目标模板文件,若错误被静默吞掉就会返回空字符串。
2. 冗余的异步包装(非直接诱因,但会增加排查成本)
你使用的readFileSync是Node.js同步文件读取API,不需要用async/await和then链式调用包装,冗余的异步逻辑会混淆错误排查方向。
3. 缺少错误捕获
readFileSync读取不存在的路径时会抛出ENOENT错误,如果你没有做错误捕获,部分Jest默认配置会吞掉这类异常,导致返回空字符串而非明确报错。
解决步骤
第一步:路径修正
不要用__dirname做相对路径拼接,改为基于项目根目录定位文件,比如用process.cwd()(Jest运行时process.cwd()默认指向项目根目录)拼接路径:
import { join } from 'path'; import { readFileSync } from 'fs'; // 修正read_template,显式指定编码,移除不必要的async export function read_template(path: string){ try { return readFileSync(path, 'utf-8'); } catch (err) { // 增加错误捕获,避免静默失败 throw new Error(`模板读取失败,路径:${path},错误:${(err as Error).message}`); } } // 修正get_template的路径拼接逻辑,移除不必要的async export function get_template(template_name: string) { // 假设templates文件夹在项目根目录下,可根据实际目录结构调整 const path = join(process.cwd(), 'templates/template-data', `${template_name}.hbs`); const data = read_template(path); console.log('common.ts: ', data); return data; }
第二步:测试用例简化
移除不必要的异步逻辑:
test("getting a existing template", () =>{ const template = get_template(template_name); console.log('template: ', template); expect(template).toBe(user_input_template); });
第三步:额外排查(如果修改路径后仍返回空)
检查你的Jest配置文件(jest.config.js/jest.config.ts),是否对.hbs后缀的文件配置了mock规则,比如类似以下的配置会把所有模板文件返回空:
moduleNameMapper: { '\\.(hbs|css|scss)$': '<rootDir>/__mocks__/fileMock.js' }
如果存在该规则,要么删除对.hbs的mock配置,要么将你的模板目录排除在mock规则外。
内容的提问来源于stack exchange,提问作者Malte Teichert
相关产品推荐
相关产品推荐

