Angular迁移至Jest时Mock document.head报getAttribute为null错误
解决Jest中Angular WrapperService静态属性BASE_PATH的document Mock问题
问题根源
WrapperService的静态属性BASE_PATH是在类被导入时立即执行document.head.querySelector("base").getAttribute("href")初始化的,如果你的setup-jest.ts中DOM设置时机晚于服务类的加载,就会出现null报错。以下是几种可行的Mock方案:
方案一:提前Mock document的querySelector方法
在服务类被导入之前,直接Mockdocument.head.querySelector方法,确保调用"base"选择器时返回模拟元素:
- 单测试文件局部Mock(在导入服务前执行):
// 必须放在import WrapperService的代码之前 const mockBaseElement = { getAttribute: jest.fn(() => '/your-test-base-path/') }; document.head.querySelector = jest.fn(selector => selector === 'base' ? mockBaseElement : null); // 之后再导入服务 import { WrapperService } from './path-to-wrapper-service';
- 全局生效(在
setup-jest.ts最顶部执行):
// setup-jest.ts最开头添加 const mockBase = { getAttribute: jest.fn(() => '/default-base-path/') }; document.head.querySelector = jest.fn(sel => sel === 'base' ? mockBase : null); // 再加载jest-preset-angular等初始化代码 import 'jest-preset-angular/setup-jest';
方案二:直接Mock静态属性BASE_PATH
跳过对document的依赖,直接Mock服务的静态属性:
import { WrapperService } from './path-to-wrapper-service'; beforeAll(() => { // 如果BASE_PATH是getter属性 jest.spyOn(WrapperService, 'BASE_PATH', 'get').mockReturnValue('/mocked-base/'); // 如果是普通静态属性,可直接赋值 // (WrapperService as any).BASE_PATH = '/mocked-base/'; });
方案三:提前在setup-jest.ts中插入base标签
确保base标签在Angular服务加载前就被插入到DOM中:
// setup-jest.ts最顶部执行 const baseEl = document.createElement('base'); baseEl.setAttribute('href', '/your-base-path/'); document.head.appendChild(baseEl); // 再执行后续初始化逻辑 import 'jest-preset-angular/setup-jest';
内容的提问来源于stack exchange,提问作者G.S Abhaypal
相关产品推荐
相关产品推荐

