Angular集成Jest测试组件时全局JS常量报ReferenceError解决方案
Angular集成Jest测试时全局JS常量缺失的解决方案
问题根因
Jest运行在Node环境,不会加载项目中JSP片段注入的浏览器端全局变量。Angular组件类的static readonly属性会在模块导入阶段立即求值,此时读取未定义的maxFileUploadSizeInKb、maxImageFileUploadSizeInKb就会抛出ReferenceError。
以下是两种可落地的解决方式,可根据场景选择:
方案1:单个测试文件内注入变量(仅当前文件生效)
注意:组件静态属性在模块导入时就会执行求值,不要把变量赋值放在beforeAll/beforeEach钩子里——这类钩子执行时机晚于模块导入,赋值会失效。
直接在测试文件的最顶部,所有import语句之前给全局对象挂载对应常量即可:
// 必须先赋值,再导入依赖的组件模块 (globalThis as any).maxFileUploadSizeInKb = '5000'; (globalThis as any).maxImageFileUploadSizeInKb = '400'; // 之后再写所有导入语句 import { QuestionComponent } from './question.component'; // 其余测试相关import... describe('QuestionComponent', () => { // 正常写测试逻辑即可 });
如果确实需要在beforeAll中动态设置变量值,需要配合动态import延迟加载被测组件,写法繁琐,仅在需要针对不同用例切换常量值时使用:
describe('QuestionComponent', () => { let QuestionComponent: any; beforeAll(async () => { (globalThis as any).maxFileUploadSizeInKb = '5000'; (globalThis as any).maxImageFileUploadSizeInKb = '400'; // 等全局变量赋值完成后再动态导入组件模块 const module = await import('./question.component'); QuestionComponent = module.QuestionComponent; }); // 测试逻辑... });
方案2:全局Setup文件统一预定义(所有测试生效,推荐)
适合项目中多处依赖这类JSP注入全局常量的场景,一次配置所有测试文件通用:
- 在项目根目录新建
custom-jest-constants.setup.ts文件,统一维护所有全局常量的测试默认值:
// 所有JSP注入的全局JS常量都可在此统一mock Object.assign(globalThis, { maxFileUploadSizeInKb: '5000', maxImageFileUploadSizeInKb: '400', // 后续新增其他缺失的全局变量,直接在这里追加即可 });
- 修改根目录
jest.config.ts配置,将该setup文件加入setupFiles数组。注意要使用setupFiles而非setupFilesAfterEnv:setupFiles会在所有测试模块导入之前执行,刚好匹配组件静态属性的初始化时机:
export default { clearMocks: true, globalSetup: 'jest-preset-angular/global-setup', preset: 'jest-preset-angular', // 新增这行,自定义全局常量setup文件 setupFiles: ['<rootDir>/custom-jest-constants.setup.ts'], setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'], };
- (可选TS类型兼容)如果TS编译时提示全局变量类型不存在,可在项目的全局类型声明文件(通常是
src/typings.d.ts,没有则新建)中补充声明:
declare const maxFileUploadSizeInKb: string; declare const maxImageFileUploadSizeInKb: string;
配置完成后直接执行npm test即可正常跑通所有用例。
常见踩坑点
- 不要把全局常量赋值逻辑放在
setupFilesAfterEnv对应的setup文件中,该配置项的执行时机在测试框架安装完成后,部分依赖模块已经完成加载,静态属性已经初始化,依然会报变量未定义错误 - 单文件测试时不要把赋值逻辑放在导入语句之后,否则模块加载时依然读不到变量值
内容的提问来源于stack exchange,提问作者Kevin Cruijssen
相关产品推荐
相关产品推荐

