如何使用Jest的beforeAll加载测试用例?异步场景报错排查
问题根源
Jest的执行分两个阶段:
- 先同步扫描所有
describe块,收集里面的测试用例,这时候beforeAll这类钩子还没运行; - 等所有测试用例收集完,才会运行钩子函数,再执行测试。
你代码里的test.each(samples)是在收集测试用例的时候就被求值了,这时候beforeAll还没给samples赋值,它还是undefined,所以才会报那个错。
解决方法
因为你要异步加载测试数据,不能在收集测试用例的时候依赖还没初始化的变量,得改用动态生成测试用例的方式,等数据加载完再创建测试:
异步加载+动态生成测试
describe(`Test Samples`, () => { beforeAll(async () => { // 替换成你的异步加载逻辑,比如调用API、读取文件等 const samples = await new Promise<string[]>(resolve => { setTimeout(() => resolve(["first sample foo", "second foo sample"]), 100); }); // 遍历加载好的样本,逐个创建测试用例 samples.forEach(sample => { test(`should include foo in "${sample}"`, () => { expect(sample.includes("foo")).toBe(true); }); }); }); // 可选:添加一个占位测试,避免describe因无测试用例报错 test("等待异步测试生成", () => { expect(true).toBe(true); }); });
替代方案(Jest 27+可用)
如果你的Jest版本在27及以上,可以利用test.each支持函数返回数组的特性,让数组在测试执行阶段才求值:
let samples: string[]; beforeAll(async () => { samples = await fetchSamplesFromExternalSource(); // 你的异步加载逻辑 }); describe(`Test Samples`, () => { test.each(() => samples)("should include foo", (sample) => { expect(sample.includes("foo")).toBe(true); }); });
这样() => samples会在beforeAll执行完后才被调用,此时samples已经是有效的数组了。
内容的提问来源于stack exchange,提问作者user358041
相关产品推荐
相关产品推荐

