Jest测试中无法修改全局变量的问题求助
问题:无法在测试中修改模块内全局变量的值
我有一段JavaScript代码,需要基于全局变量测试结果,以下是简化示例:
模块代码(future.js)
let newHire = false; //Global variable const cert = () => { if (newHire) { console.log('newhire is true'); } else { console.log('newhire is false'); } return newHire; }; module.exports = { cert, };
测试代码(future.test.js)
const mapper = require('../../../libs/future'); describe('Test that cert is working', () => { it('Test cert', () => { mapper.newHire = true; const result = mapper.cert(); expect(result).toEqual(true); }); });
运行测试后始终得到错误:
expect(received).toEqual(expected) // deep equality Expected: true Received: false
显然无法在测试中修改newHire的值,请问该如何解决?
解决方案
核心原因:你在测试中给mapper.newHire赋值,只是给模块导出的对象添加了一个新属性,但模块内部的newHire变量是独立的局部变量,和导出对象没有关联,所以修改它不会影响cert函数的执行结果。
以下是三种可行的解决方法:
方法1:将全局变量转为导出对象的属性
修改模块代码,让内部函数直接引用导出对象上的属性,这样外部修改就能同步生效:
// future.js module.exports = { newHire: false, cert() { if (module.exports.newHire) { console.log('newhire is true'); } else { console.log('newhire is false'); } return module.exports.newHire; } };
测试代码无需修改,原有的mapper.newHire = true即可生效。
方法2:添加专门的变量设置接口
如果不想直接暴露newHire变量,可以在模块中新增一个用于修改它的函数,只导出必要的接口:
// future.js let newHire = false; const cert = () => { if (newHire) { console.log('newhire is true'); } else { console.log('newhire is false'); } return newHire; }; const setNewHire = (value) => { newHire = value; }; module.exports = { cert, setNewHire };
测试代码调用新增的设置函数:
// future.test.js const mapper = require('../../../libs/future'); describe('Test that cert is working', () => { it('Test cert', () => { mapper.setNewHire(true); const result = mapper.cert(); expect(result).toEqual(true); }); });
方法3:用依赖注入重构代码(推荐)
彻底消除全局变量依赖,将newHire作为参数传入cert函数,让函数逻辑更纯粹,测试也更灵活:
// future.js // 保留默认参数,兼容原有调用方式 const cert = (newHire = false) => { if (newHire) { console.log('newhire is true'); } else { console.log('newhire is false'); } return newHire; }; module.exports = { cert, };
测试时直接传入对应参数即可:
// future.test.js const mapper = require('../../../libs/future'); describe('Test that cert is working', () => { it('Test cert with newHire true', () => { const result = mapper.cert(true); expect(result).toEqual(true); }); it('Test cert with newHire false', () => { const result = mapper.cert(false); expect(result).toEqual(false); }); });
内容的提问来源于stack exchange,提问作者R.Almoued
相关产品推荐
相关产品推荐

