如何测试 angular 2 组件,其中嵌套组件具有自己的依赖项? (TestBed.configureTestingModule)

Posted

技术标签:

【中文标题】如何测试 angular 2 组件,其中嵌套组件具有自己的依赖项? (TestBed.configureTestingModule)【英文标题】:How to test angular 2 component with nested components inside with their own dependencies ? (TestBed.configureTestingModule) 【发布时间】:2017-08-14 12:01:46 【问题描述】:

我有一个组件 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 没有自己的依赖项。在这里我很困惑,如果我每次都必须导入和移除所有其他组件,我该如何进行单元测试?看起来工作量很大。还有其他方法吗?使用具有自己依赖关系的嵌套组件测试组件的最佳实践是什么?

非常感谢,

史蒂芬。

【问题讨论】:

你试过schemas: [NO_ERRORS_SCHEMA]吗? blog.nrwl.io/essential-angular-testing-192315f8be9b#.vygkcekn0 【参考方案1】:

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

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

仅当组件本身提供了依赖项时,才需要在overrideComponent 中设置providers。 (如果您在comp-A.ts 中有提供者列表)

假设comp-b 需要在您的comp-A 覆盖中提供comp-AServicecomp-AService,因为comp-bcomp-A 的子级,它将为其提供comp-AService

如果您在 app.module 或高于组件本身的位置提供这些依赖项,则无需覆盖。例如,如果 comp-b 需要 comp-AServicesomeOtherService 两者都在您的 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-components-scenarios#nested-component-tests

【讨论】:

NO_ERROR_SCHEMA 有什么作用?这是否意味着您要忽略所有子组件:medium.com/@voorkanter/…? @skofgar NO_ERROR_SHEMA 告诉编译器忽略无法识别的元素和属性。您可以在此处阅读有关在测试中使用它的更多信息:angular.io/docs/ts/latest/testing/#!#shallow-component-test 我已更新答案以包含此链接 感谢您添加信息! 当然,不用担心 :)【参考方案2】:

听从@yurzui 的建议:

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

【讨论】:

【参考方案3】:

这是一个老问题,但这是我目前在 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'),
    ]
  );

【讨论】:

以上是关于如何测试 angular 2 组件,其中嵌套组件具有自己的依赖项? (TestBed.configureTestingModule)的主要内容,如果未能解决你的问题,请参考以下文章

如何将数据绑定到 Angular 2 中的多个嵌套组件?

Angular 2 - 单元测试绑定到嵌套的自定义表单控件

Angular 2+/4/5/6/7:智能、愚蠢和深度嵌套的组件通信

在 Angular 中动态创建的嵌套组件

更新嵌套 Angular 2 组件中的数字字段值

如何使用 Angular 中的依赖注入将属性指令实例传递给嵌套组件