7

我有MainComponentChildComponentA用作@ViewChild. MainComponent正在调用一个方法ChildComponentA

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

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

我尝试使用

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

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

4

2 回答 2

6

我认为在这种情况下,您可以尝试用模拟组件替换子组件。只需使用相同的选择器创建一个模拟组件并使用 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/

于 2016-09-07T11:08:32.790 回答
2

请注意,如果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具有相同的选择器,这个应该可以工作。

为这个问题给出的另一个答案适用于从不同模块带入TestBedChildComponent情况。

笔记

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

于 2019-09-04T21:55:54.057 回答