角单元测试-使用存根模拟子组件

时间:2019-12-11 17:18:15

标签: angular typescript unit-testing jasmine

我试图对具有要模拟的子组件的组件进行单元测试。我不想使用NO_ERRORS_SCHEMA引起相关的缺点。我正在尝试使用存根/虚拟子组件。代码如下:

parent.component.ts

@Component({
  selector: 'parent',
  template: `
    <!-- Does other things -->
    <child></child>
  `
})
export class ParentComponent { }

child.component.ts

@Component({
  selector: 'child',
  template: '<!-- Does something -->'
})
export class ChildComponent {
  @Input() input1: string;
  @Input() input2?: number;
}

parent.component.spec.ts

describe('ParentComponent', () => {
  let component: ParentComponent;
  let fixture: ComponentFixture<ParentComponent>;
  let router: Router;

  @Component({
    selector: 'child',
    template: '<div></div>'
  })
  class ChildStubComponent {
    @Input() input1: string;
    @Input() input2: number;
  }

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ ParentComponent, ChildStubComponent ],
      imports: [
        AppRoutingModule, HttpClientModule, BrowserAnimationsModule,
        RouterTestingModule.withRoutes(routes)
      ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ParentComponent);
    component = fixture.componentInstance;
    router = TestBed.get(Router);
    spyOnProperty(router, 'url', 'get').and.returnValue('/somePath');
    fixture.detectChanges();
  });

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

我遇到的问题是angular抱怨了以下错误:

Failed: Template parse errors:
More than one component matched on this element.
Make sure that only one component's selector can match a given element.

如果有帮助,我正在使用Angular 8。到目前为止,我所看到的所有地方都表明您以与现在相同的方式对子组件进行了存根处理。目前无法使用ngMocks。

编辑 使用ngMock尝试过,但这只具有相同的问题。任何帮助将不胜感激!

解决方案

使其正常工作。问题在于AppRoutingModule已导入了真实组件。

1 个答案:

答案 0 :(得分:0)

对于嵌套组件,我们可以这样模拟它们:https://angular.io/guide/testing#stubbing-unneeded-components

最后,您的 parent.component.spec.ts 应该是:

import { HttpClientTestingModule} from '@angular/common/http/testing';
import { Component } from '@angular/core';

describe('ParentComponent', () => {
  let component: ParentComponent;
  let fixture: ComponentFixture<ParentComponent>;
  let router: Router;


 @Component({selector: 'child', template: ''})
 class ChildStubComponent {}

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ ParentComponent, ChildStubComponent ],
      imports: [
        AppRoutingModule, HttpClientTestingModule, BrowserAnimationsModule,
        RouterTestingModule.withRoutes(routes)
      ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ParentComponent);
    component = fixture.componentInstance;
    router = TestBed.get(Router);
    spyOnProperty(router, 'url', 'get').and.returnValue('/somePath');
    fixture.detectChanges();
  });

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