我有一个组件 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 没有自己的依赖项。在这里我很困惑,如果我每次都必须导入和重新模拟所有其他组件,我该如何进行单元测试?看起来工作量非常大。还有别的办法吗?使用具有自己的依赖项的嵌套组件测试组件的最佳实践是什么?
非常感谢,
史蒂芬。
如果您不需要在测试中以任何方式引用
comp-b
,您可以将 schemas: [NO_ERRORS_SCHEMA] or [CUSTOM_ELEMENTS_SCHEMA]
添加到 TestBed
配置中,或覆盖 comp-A
的模板并删除 comp-b
的标签
如果您确实需要引用
comp-b
,您可能不需要在覆盖中专门提供它的依赖项。
仅当组件本身提供依赖项时,才需要在 providers
中设置
overrideComponent
。 (如果您有
comp-A.ts
中的提供商列表)假设
comp-b
需要
comp-AService
并且
comp-AService
正在您的
comp-A
覆盖中提供,因为
comp-b
是
comp-A
的子级,它将为其提供
comp-AService
。如果您在
app.module
或高于组件本身的位置提供这些依赖项,则无需覆盖。例如,如果
comp-b
需要
comp-AService
和
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-components-scenarios#nested-component-tests
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [comp-a],
schemas: [NO_ERRORS_SCHEMA]
})
.compileComponents();
}));
这是一个老问题,但这就是我目前在 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'),
]
});
@Component({独立: true, 模板: '', 选择器: 'comp-b' }) 导出类 CompBComponent { }
TestBed.configureTestingModule({ 进口:[ 组合B组件 ] });