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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 23:45:21