Jest中如何在beforeEach和afterEach钩子之间共享变量
Jest跨beforeEach/afterEach共享测试资源ID的实现方案
正确的变量共享写法
不要在beforeEach钩子内部用const声明ID,这个变量的作用域会被限制在钩子函数内部,afterEach和测试用例都访问不到。你只需要把变量声明在describe块的作用域下即可,这个作用域下的变量对同个describe下的所有钩子、测试用例都可见,而且每个describe块的作用域是独立的,不会和其他测试块冲突。
注意你原代码里的axios.post是异步请求,必须加await等待返回结果,不然拿到的会是Promise对象而不是实际生成的资源ID。
修正后的代码示例:
describe('test', () => { // 在describe块级作用域声明共享变量 let testResourceId; beforeEach(async () => { // 等待异步请求完成,拿到服务端返回的ID const res = await axios.post('/your/resource/api', { /* 种子数据 */ }); testResourceId = res.data.id; }); afterEach(async () => { // 直接访问作用域内的变量执行清理 await axios.delete(`/your/resource/api/${testResourceId}`); }); it('测试用例逻辑', () => { // 测试逻辑里也能直接拿到testResourceId使用 console.log('当前测试资源ID:', testResourceId); }); });
如果你不想在块级作用域声明变量,也可以用Jest自带的测试上下文:把钩子函数写成普通函数(不要用箭头函数),通过this挂载变量,每个测试用例的上下文是完全独立的,写法如下:
describe('test', () => { beforeEach(async function() { const res = await axios.post('/your/resource/api', {}); this.testResourceId = res.data.id; }); afterEach(async function() { await axios.delete(`/your/resource/api/${this.testResourceId}`); }); it('测试用例逻辑', function() { console.log(this.testResourceId); }); });
全局上下文存储变量是否安全?
完全不安全,不要这么做,核心原因有两点:
- Jest默认会并行执行多个测试文件的用例,全局变量会被多个测试流程共同读写,很容易出现A测试写入的ID被B测试覆盖,最终清理时删错资源、或者漏删数据的问题,引发偶发的测试失败,排查成本极高。
- 全局变量会破坏测试的隔离性,单个测试用例的副作用会扩散到整个测试进程,不符合单元测试独立运行的要求。
内容的提问来源于stack exchange,提问作者teteyi3241
相关产品推荐
相关产品推荐

