Angular测试报错:this.modal.nativeElement.present不是函数求解决
Angular组件测试:解决TypeError: this.modal.nativeElement.present is not a function
问题根源
你的组件通过@ViewChild('modal')获取的是外部库的ExtLibModal组件实例,而非普通ElementRef。测试时若未正确模拟该组件实例的nativeElement属性及present方法,就会抛出该错误。
解决方案
方案1:直接模拟Modal实例及nativeElement
创建包含nativeElement结构的mock对象,直接赋值给组件的modal属性,跳过外部组件依赖:
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MyComponent } from './my.component'; import { NO_ERRORS_SCHEMA } from '@angular/core'; describe('MyComponent', () => { let component: MyComponent; let fixture: ComponentFixture<MyComponent>; // 模拟外部Modal的nativeElement结构,包含需要的方法 const mockModal = { nativeElement: { present: jasmine.createSpy('present'), addEventListener: jasmine.createSpy('addEventListener') // 若组件绑定事件,需加入对应方法 } }; beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [MyComponent], // 用NO_ERRORS_SCHEMA忽略模板中未知的外部组件标签 schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); fixture = TestBed.createComponent(MyComponent); component = fixture.componentInstance; // 给组件的modal属性赋值mock对象 component.modal = mockModal as any; // 触发ngAfterViewInit生命周期 fixture.detectChanges(); }); it('should call modal.present() after view init', () => { expect(mockModal.nativeElement.present).toHaveBeenCalled(); }); });
方案2:创建模拟的外部Modal组件
若不想使用NO_ERRORS_SCHEMA,可以声明一个模拟的外部组件类,匹配原组件结构:
import { Component } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MyComponent } from './my.component'; // 模拟外部库的Modal组件 @Component({ selector: 'ext-lib-modal', template: '' }) class MockExtLibModal { // 模拟组件的nativeElement及方法 nativeElement = { present: () => {}, addEventListener: () => {} }; } describe('MyComponent', () => { let component: MyComponent; let fixture: ComponentFixture<MyComponent>; beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [MyComponent, MockExtLibModal] // 声明模拟组件 }).compileComponents(); fixture = TestBed.createComponent(MyComponent); component = fixture.componentInstance; // spyOn nativeElement上的present方法 spyOn(component.modal.nativeElement, 'present'); fixture.detectChanges(); }); it('should invoke modal present method', () => { expect(component.modal.nativeElement.present).toHaveBeenCalled(); }); });
关键注意点
- 不要尝试注入
ElementRef,因为@ViewChild('modal')获取的是外部组件实例,而非原生DOM元素的ElementRef。 - 若组件中还绑定了Modal的事件,需在mock对象中加入对应的事件监听方法(如
addEventListener),避免测试报错。
内容的提问来源于stack exchange,提问作者sandeep ghansiala
相关产品推荐
相关产品推荐

