Angular应用Jest测试中AnimationEvent未定义,求Mock解决方法
解决Jest环境中Mock AnimationEvent的问题
确实,Jest默认的jsdom环境并没有内置AnimationEvent这个API,这就是你遇到ReferenceError: AnimationEvent is not defined的核心原因。下面给你几个实用的Mock方案,你可以根据测试场景选择:
方案一:在单个测试文件中局部Mock
如果只是某个测试文件需要用到AnimationEvent,可以在测试文件的beforeEach钩子中手动模拟这个构造函数:
beforeEach(() => { // 全局注册AnimationEvent模拟类 global.AnimationEvent = class AnimationEvent { constructor(type: string, options?: AnimationEventInit) { this.type = type; // 模拟你需要用到的属性,比如这里的animationName this.animationName = options?.animationName ?? ''; // 可选:根据组件逻辑补充其他必要属性 this.bubbles = options?.bubbles ?? false; this.cancelable = options?.cancelable ?? false; this.elapsedTime = options?.elapsedTime ?? 0; } type: string; animationName: string; bubbles: boolean; cancelable: boolean; elapsedTime: number; } as typeof AnimationEvent; }); // 之后你的测试代码就可以正常使用了 test('触发animationend事件', () => { const element = fixture.nativeElement; element.dispatchEvent(new AnimationEvent("animationend", { animationName: "slide-down" })); fixture.detectChanges(); // 断言组件的预期行为 });
方案二:全局Mock(所有测试文件通用)
如果多个测试文件都需要用到AnimationEvent,可以在Jest的全局配置文件中一次性Mock,避免重复代码:
- 首先创建一个全局配置文件,比如
setup-jest.ts:
// setup-jest.ts global.AnimationEvent = class AnimationEvent { constructor(public type: string, options?: AnimationEventInit) { this.animationName = options?.animationName ?? ''; this.bubbles = options?.bubbles ?? false; this.cancelable = options?.cancelable ?? false; this.composed = options?.composed ?? false; this.elapsedTime = options?.elapsedTime ?? 0; this.pseudoElement = options?.pseudoElement ?? ''; } animationName: string; bubbles: boolean; cancelable: boolean; composed: boolean; elapsedTime: number; pseudoElement: string; } as typeof AnimationEvent;
- 然后在
jest.config.js中配置这个文件为全局初始化脚本:
module.exports = { // 其他Jest配置项... setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'], };
方案三:轻量Mock(仅模拟必要属性)
如果你的组件逻辑只用到了AnimationEvent的少数属性(比如type和animationName),可以用Jest的函数Mock来简化:
beforeEach(() => { global.AnimationEvent = jest.fn((type, options) => ({ type, animationName: options?.animationName, bubbles: options?.bubbles ?? false, cancelable: options?.cancelable ?? false, })) as unknown as typeof AnimationEvent; });
这种方式更轻量,适合只需要触发事件、不需要完整API的场景。
不管用哪种方案,Mock完成后你原来的dispatchEvent代码就能正常执行,触发组件中对应的事件处理逻辑了。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

