Jest测试Next.js/React项目时window.dataLayer未定义问题求助
解决Jest测试中window.dataLayer未定义及eventCallback报错的方案
正确初始化并Mock window.dataLayer
测试环境里window.dataLayer默认不存在,得先在beforeEach里初始化这个数组(和生产环境结构保持一致),同时Mockpush方法时要自动执行传入的eventCallback,不然会触发函数不存在的报错:
beforeEach(() => { // 初始化dataLayer为数组,对齐生产环境的结构 window.dataLayer = window.dataLayer || []; // Mock push方法,自动处理eventCallback jest.spyOn(window.dataLayer, 'push').mockImplementation((config) => { // 检查并执行传入的eventCallback,避免报错 if (typeof config.eventCallback === 'function') { config.eventCallback(); } return null; // 可选:匹配原push方法的返回值,根据实际情况调整 }); }); afterEach(() => { // 清理Mock,防止测试用例之间互相污染 jest.restoreAllMocks(); });
之前的方法为啥失败?
- 第一种
jest.spyOn(window.dataLayer, 'push')报错:因为一开始window.dataLayer是undefined,没法对不存在的对象方法做spy。 - 第二种
jest.spyOn(window, 'dataLayer' ,'push')参数错了:spyOn的第三个参数是访问器类型(get/set),不是方法名,语法本身就不对。 - 第三种直接赋值但没处理
eventCallback:代码里调用dataLayer.push时传了带eventCallback的配置,Mock的push没执行这个回调,所以触发了类型错误。
额外提示
- 如果项目里
dataLayer还有其他方法(比如get),可以在初始化的时候一起Mock。 - 大型Next.js项目可以把
window.dataLayer的全局初始化放到setupTests.js(或jest.setup.js)里,不用每个测试文件重复写。
内容的提问来源于stack exchange,提问作者CodingCoder
相关产品推荐
相关产品推荐

