Jest测试环境如何为指定测试或全部测试关闭严格模式
根本原因说明
你遇到的报错是ECMAScript严格模式的内置限制,ES模块默认启用严格模式,且全局开启的严格模式无法局部关闭。你之前尝试的方案失效大概率是因为React项目的编译链路(一般是Babel)默认给所有代码加了严格模式标识,覆盖了tsconfig的配置。另外你入口文件里的<React.StrictMode>是React框架的运行时检查规则,和ECMAScript语言层面的严格模式完全无关,不需要修改这部分代码。
方案1:优化测试逻辑(更推荐)
你测试的核心目标是验证gtag函数正确把调用参数推入dataLayer,callee属于arguments对象的内置属性,只要确实推入的是arguments对象,该属性必然存在,不需要额外断言。你前面的4条断言已经足够覆盖测试目标,直接删掉expect(window.dataLayer[0]).toHaveProperty('callee')即可解决报错。
如果你一定要确认推入的是arguments对象而非普通数组,可以用如下判断代替,该判断在严格模式下也能正常执行,不会触发报错:
expect(Object.prototype.toString.call(window.dataLayer[0])).toBe('[object Arguments]')
方案2:为特定文件关闭严格模式
如果你必须保留callee相关的断言,可以通过修改编译配置让指定文件不启用严格模式:
大部分React+TS项目都用Babel处理代码,此时tsconfig的noImplicitUseStrict配置不会生效,需要修改Babel配置,在你的babel.config.js或者.babelrc中添加overrides规则,针对你的被测文件和测试文件关闭严格模式即可:
{ "overrides": [ { "test": ["src/path/to/file.ts", "src/path/to/file.test.ts"], "presets": [ ["@babel/preset-env", { "strictMode": false }], "@babel/preset-typescript" ] } ] }
你也可以把被测代码单独抽离为CommonJS文件:将文件后缀改为.cjs,使用module.exports导出,测试文件用require引入,CommonJS规范默认不会开启全局严格模式,只要你没有手动加'use strict'标识就可以正常访问callee属性。
内容的提问来源于stack exchange,提问作者Raz Luvaton

