首页 > 解决方案 > 单元测试中的错误(业力)。没有将“exportAs”设置为“ngbPopover”的指令

问题描述

我在我的角度页面中使用下面的 ngbPopover 并为它编写单元测试。它给我一个编译错误。像下面

没有将“exportAs”设置为“ngbPopover”(click)="p1.open()" [ERROR ->]#p1="ngbPopover"> 的指令

    <span placement="bottom"  [ngbPopover]="popContent"  triggers="manual"
          (click)="p1.open()" #p1="ngbPopover">
    </span>




    import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NotificationsService as ToasterService } from 'angular2-notifications';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

import { testComponent } from './test.component';

describe('testComponent', () => {
  let component: testComponent;
  let fixture: ComponentFixture<testComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [testComponent],
      imports: [ FormsModule, ReactiveFormsModule  ],
    }).compileComponents();
  }));

  beforeEach(() => {
    const toasterServiceStub = {
      create: () => ({})
    };
    TestBed.configureTestingModule({
      declarations: [testComponent],
      schemas: [NO_ERRORS_SCHEMA],
      providers: [
        { provide: ToasterService, useValue: toasterServiceStub }
      ]
    });
    fixture = TestBed.createComponent(testComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
    fixture = TestBed.createComponent(testComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

如果我从 html 中删除该 #p1,我的单元测试就会被编译。但不确定为什么会导致错误。请帮帮我

标签: angularunit-testingkarma-jasmine

解决方案


如果您只想在没有构建 DOM 的情况下进行单元测试,请使用以下设置:

describe('testComponent', () => {
  let component: testComponent;

  // Note that you have to initialize the component only *once* via the TestBed, not multiples times as you did.
  beforeEach(() => {
    const toasterServiceStub = {
      create: () => ({}),
    };

    TestBed.configureTestingModule({
      providers: [
        testComponent,
        {provide: ToasterService, useValue: toasterServiceStub},
      ],
    });

    component = TestBed.get(testComponent);
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

如果您想要的测试应该是一个集成测试,您希望确保正确解析 HTML,那么您的实现过于频繁地初始化组件并且至少错过了 Ngb 的导入

describe('testComponent', () => {
  let component: testComponent;
  let fixture: ComponentFixture<testComponent>;

  // // Only configure the testing module once, not multiple times.
  // beforeEach(async(() => {
  //   TestBed.configureTestingModule({
  //     declarations: [testComponent],
  //     imports: [ FormsModule, ReactiveFormsModule  ],
  //   }).compileComponents();
  // }));

  beforeEach(() => {
    const toasterServiceStub = {
      create: () => ({})
    };

    TestBed.configureTestingModule({
      declarations: [testComponent],
      imports: [FormsModule, ReactiveFormsModule, NgbModule], // Here you were missing the NgbModule. You may also just import the sub-modules you're explicitely using (such as pagination)
      schemas: [NO_ERRORS_SCHEMA],
      providers: [
        { provide: ToasterService, useValue: toasterServiceStub }
      ]
    });
    fixture = TestBed.createComponent(testComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();

    // You do not need to do this twice.
    // fixture = TestBed.createComponent(testComponent);
    // component = fixture.componentInstance;
    // fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

任何一种实现都应该适用于您的情况。这些实现之间的区别在于,第一个实现不会构建整个 HTML DOM,而第二个实现会构建。要使第一个工作正常,HTML 中使用的所有模块都需要存在。第二个实现基本上只是初始化组件及其注入的依赖项。


推荐阅读