You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,避免重复代码:

  1. 首先创建一个全局配置文件,比如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;
  1. 然后在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:46:34