【问题标题】:Angular Unit Testing - Mock Child Component using StubAngular 单元测试 - 使用 Stub 模拟子组件
【发布时间】:2020-04-05 00:57:23
【问题描述】:

我正在尝试对具有要模拟的子组件的组件进行单元测试。我不想使用 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 已经导入了真正的组件。

【问题讨论】:

  • 您可能已经在 AppRoutingModule 中声明了(真正的)子组件。
  • 是否可以导入没有该组件的模块只是为了测试?
  • 您可以使用angular.io/api/core/testing/TestBed#overrideModule 来完成。但我会首先避免导入这个模块。在测试模块中导入/声明您需要的内容。
  • 太棒了!我让它工作了。谢谢!!

标签: angular typescript unit-testing jasmine


【解决方案1】:

对于嵌套组件,我们可以这样模拟它们:https://angular.io/guide/testing-components-scenarios#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();
  });
});

【讨论】:

    猜你喜欢
    • 2016-11-23
    • 1970-01-01
    • 2021-01-05
    • 2020-06-19
    • 2020-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多