使用 TestBed 覆盖组件

OverrideComponent with TestBed

我有 MainComponent 使用 ChildComponentA 作为 @ViewChildMainComponent 正在调用 ChildComponentA 上的方法。

我想编写一个模拟单元测试用例ChildComponentA。我如何使用 TestBed(在 Angular 2 RC5 中)做到这一点?

在我使用 overrideDirective(MainComponentName, ChildComponentA, MockChildComponentA); 之前,是否有与此等效的使用 TestBed

我试过使用

TestBed.overrideComponent(ChildComponentA,{
        set: {
          template: '<div></div>'
        }
      }); 

这只是设置模板,但我也想模拟组件中的方法。

我认为在这种情况下您可以尝试将子组件替换为模拟组件。只需创建一个具有相同选择器的模拟组件,然后使用 TestBed 删除真实子组件的声明并将声明添加到您的模拟组件。

@Component({
  selector: 'child',
  template: '<div></div>'
})
class MockComponent {

}

并在您的测试中执行此操作以使用模拟组件:

    TestBed.configureTestingModule({
        imports: [MyModule],
        declarations: [ParentComponent, MockComponent]
    });

    TestBed.overrideModule(MyModule, {
        remove: {
            declarations: [ParentComponent, ChildComponent],
            exports: [ParentComponent, ChildComponent]
        }
    });

此处有更多详细信息:https://github.com/angular/angular/issues/10689。 确保重新声明 ParentComponent,否则它不起作用(不知道为什么)。

如果使用@ViewChild获取子组件的引用,需要修改为不使用组件的类型,而是使用id。使用@ViewChild('child') 而不是@ViewChild(ChildComponent)。请参阅此处的第二个示例:http://learnangular2.com/viewChild/

请注意,如果 ChildComponent 是在 TestModule 本身中声明的,则无需覆盖声明原始模块的模块。

因此,如果您的 TestBed 声明如下所示:

TestBed.configureTestingModule({
    declarations: [
        ParentComponent,
        ChildComponent         // This is what you'd like to mock
    ]
});

然后,要覆盖 ChildComponent,您只需要:

@Component({
    selector: 'child',
    template: '<div></div>'
})
class MockChildComponent {
}

TestBed.configureTestingModule({
    declarations: [
        ParentComponent,
        MockChildComponent      // Notice the original is replaced by the mock
    ]
});

只要 ChildComponentMockChildComponent 有相同的选择器,这个就可以。

针对此问题给出的其他答案适用于 ChildComponent 另一个模块 引入 的情况测试台。

备注

如果您的 ChildComponent 有任何 @Input@Output,则将它们也包含在您的 MockChildComponent 中。