如何测试具有嵌套组件的角度2组件及其自身的依赖关系? (TestBed.configureTestingModule)

时间:2017-03-22 11:35:51

标签: angular unit-testing jasmine karma-jasmine

我有一个组件A在其模板中使用组件B,c,D:

###template-compA.html

    <comp-b></comp-b>
    <comp-c [myinput]="obj.myinput"></comp-c>
    <comp-d ></comp-d>

...等

为了简化,假设它们只是组件A中的一个指令:

 ###template-compA.html

    <comp-b></comp-b>

我的comp-b有自己的依赖项(服务或其他comp)。

如果我想以这种方式测试comp-a:

TestBed.configureTestingModule({
    declarations: [comp-A],
    imports: [ReactiveFormsModule],
}).overrideComponent(FAQListComponent, {
    set: {
    providers: [
        { provide: comp-AService, useValue: comp-AListSVC }
    ]
    }
})
    .compileComponents();

它无法正常工作。所以我这样做:

TestBed.configureTestingModule({
    declarations: [comp-A, comp-B],
    imports: [ReactiveFormsModule],
}).overrideComponent(FAQListComponent, {
    set: {
    providers: [
        { provide: comp-AService, useValue: comp-AListSVC }
    ]
    }
})
    .compileComponents();

它也不起作用,因为comp-b没有自己的依赖项。在这里我很困惑,如果我必须每次导入和重新安装所有其他组件,我怎么能进行单元测试?它看起来像是一项非常大的工作。还有另外一种方法吗?使用具有自己的依赖关系的嵌套组件测试组件的最佳实践是什么?

非常感谢,

斯特凡。

3 个答案:

答案 0 :(得分:16)

如果您不需要在测试中以任何方式引用comp-b,可以将schemas: [NO_ERRORS_SCHEMA] or [CUSTOM_ELEMENTS_SCHEMA]添加到TestBed配置中,或覆盖comp-A&# 39; s模板并删除comp-b

的标记

如果您确实需要引用comp-b,则可能不需要在覆盖中专门提供它的依赖项。

只有在组件本身中提供依赖项时,才需要在providers中设置overrideComponent。 (如果您在comp-A.ts

中有提供者列表

让我们说comp-b需要comp-AService并且comp-AService覆盖了comp-A,因为comp-bcomp-A的孩子{1}}它会为comp-AService提供。

如果您在app.module或高于组件本身的位置提供这些依赖项,则无需覆盖。例如,如果comp-b需要comp-AService&amp; someOtherService您的app.module配置中提供的TestBed可能如下所示:

TestBed.configureTestingModule({
  declarations: [comp-A, comp-B],
  imports: [ReactiveFormsModule],
  providers: [
    { provide: comp-AService, useValue: comp-AListSVC },
    { provide: someOtherService, useValue: someOtherServiceSVC }
  ]
})

修改

您可以在此处阅读有关嵌套组件测试的更多信息:

https://angular.io/guide/testing#nested-component-tests

答案 1 :(得分:1)

遵循@yurzui的建议:

beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [comp-a],
      schemas: [NO_ERRORS_SCHEMA]
    })
      .compileComponents();
  }));

答案 2 :(得分:0)

这是一个古老的问题,但这是我目前在Angular 9中所做的事情。

由于您希望尽可能地隔离测试过的组件,因此可以创建一个函数,该函数返回要导入的假组件,而不是实际的嵌套组件:

  function mockComponent(selector: string) {
    @Component({
      selector,
      template: ''
    })
    class MockValueAccessorComponent {
      // [mock implementation here]
    }

    return MockValueAccessorComponent;
  }

然后将其导入到您的TestBed中,如下所示:

  TestBed.configureTestingModule({
    declarations: [
      TestUtils.mockComponent('component-template-to-mock'),
    ]
  });