使用 TestBed 覆盖组件
OverrideComponent with TestBed
我有 MainComponent
使用 ChildComponentA
作为 @ViewChild
。 MainComponent
正在调用 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
]
});
只要 ChildComponent
和 MockChildComponent
有相同的选择器,这个就可以。
针对此问题给出的其他答案适用于 ChildComponent
被从 另一个模块 引入 的情况测试台。
备注
如果您的 ChildComponent
有任何 @Input
或 @Output
,则将它们也包含在您的 MockChildComponent
中。
我有 MainComponent
使用 ChildComponentA
作为 @ViewChild
。 MainComponent
正在调用 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
]
});
只要 ChildComponent
和 MockChildComponent
有相同的选择器,这个就可以。
针对此问题给出的其他答案适用于 ChildComponent
被从 另一个模块 引入 的情况测试台。
备注
如果您的 ChildComponent
有任何 @Input
或 @Output
,则将它们也包含在您的 MockChildComponent
中。