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

问题描述 投票:0回答:4

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

非常感谢,

史蒂芬。

angular unit-testing jasmine karma-jasmine
4个回答
24
投票

如果您不需要在测试中以任何方式引用

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


4
投票
遵循@yurzui 的建议:

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

1
投票

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

0
投票
还有另一种方法是创建一个模拟 b 组件并将其导入到组件 a 中

@Component({独立: true, 模板: '', 选择器: 'comp-b' }) 导出类 CompBComponent { }

TestBed.configureTestingModule({ 进口:[ 组合B组件 ] });

© www.soinside.com 2019 - 2024. All rights reserved.