Angular单元测试报错:element.animate is not a function 如何修复?
修复MatSnackBar测试中的
element.animate is not a function错误 问题背景
我在测试MatSnackBar组件时遇到了动画相关报错,以下是相关代码及错误信息:
组件代码
snackbarRef: MatSnackBarRef<TextOnlySnackBar>; constructor(private snackBar: MatSnackBar) {} onUpdate(){ this.snackbarRef = this.snackBar.open( `Please select at least one option`, 'Close', { panelClass: ['snackbar-failure'], duration: 5000, }, ); }
测试文件(component.spec.ts)代码
describe('ExampleComponent', () => { let component: ExampleComponent; let fixture: ComponentFixture<ExampleComponent>; let loader: HarnessLoader; beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ExampleComponent], imports: [BrowserAnimationsModule, MatSnackBarModule], providers: [MatSnackBar], }).compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(ExampleComponent); component = fixture.componentInstance; fixture.detectChanges(); loader = TestbedHarnessEnvironment.loader(fixture); }); it('should have no snackbar', async () => { expect(component.snackbarRef).toEqual(undefined); }); });
报错信息
TypeError: element.animate is not a function at WebAnimationsPlayer._triggerWebAnimation (node_modules/@angular/animations/fesm2020/browser.mjs:4442:33)
我已尝试引入NoopAnimationsModule或BrowserAnimationsModule,但均未解决问题,需要修复该测试。
修复方案
1. 模拟MatSnackBar,跳过真实动画执行
直接在测试中模拟MatSnackBar的open方法,避免触发真实DOM动画操作:
beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ExampleComponent], imports: [MatSnackBarModule], providers: [ { provide: MatSnackBar, useValue: { open: jasmine.createSpy('open').and.returnValue({}) } } ], }).compileComponents(); }));
2. 添加element.animate的Polyfill
如果需要保留真实的MatSnackBar行为,可以在测试入口文件(如test.ts)顶部添加Polyfill,模拟浏览器的animate方法:
Element.prototype.animate = () => ({ onfinish: () => {}, cancel: () => {} });
3. 通过CDK禁用测试动画
若使用Angular CDK的Harness测试组件,可在创建Fixture时直接禁用动画:
beforeEach(() => { fixture = TestBed.createComponent(ExampleComponent); component = fixture.componentInstance; // 禁用动画 fixture.componentRef.injector.get(AnimationDriver).disableAnimations(); fixture.detectChanges(); loader = TestbedHarnessEnvironment.loader(fixture); });
内容的提问来源于stack exchange,提问作者StaticName
相关产品推荐
相关产品推荐

