2016-11-29 51 views
5

假设我有一个要测试的组件,它使用了一个非常复杂的组件。此外,它使用由@viewChildren获得的参考文献调用其一些方法。例如如何将@viewChildren中使用的组件替换为测试双?

@Component({ 
     moduleId: module.id, 
     selector: 'test', 
     template: '<complex *ngFor='let v of vals'></complex>' , 
    }) 
    export class TestComponent{ 
    vals = [1,2,3,4] 
    @ViewChildren(ComplexComponent) cpxs : QueryList<ComplexComponent> 
    // .... 
    } 

如何在`TestBed'中替换测试双元的复杂组件?

喜欢的东西

@Component({ 
    moduleId : module.id, 
    selector: 'complex', template: '' 
}) 
class ComplexComponentStub { 
} 

describe('TestComponent',() => { 
    beforeEach(async(() => { 
    TestBed.configureTestingModule({ 
     declarations : [ComplexComponentStub, TestComponent], 
    }); 
it('should have four sons',()=>{ 
    let fixture = TestBed.createComponent(TestComponent); 
    let comp = fixture.componentInstance as TestComponent; 
    fixture.detectChanges(); 
    expect(comp.cpxs.length).toBe(4); 
}); 

    //.... 
})); 

对于一个完整的例子看plnkr http://plnkr.co/edit/ybdrN8VimzktiDCTvhwe?p=preview

+1

我不知道这是正确的方式,但你可以看看这个plunker https://开头plnkr。 co/edit/1w04DDKnYQ7kH6tIE0pK?p =预览 – yurzui

+0

非常感谢,作品 – user2832323

+0

然而'cpxs'似乎在我的测试中是空的......双打被有效地创建,但列表'@ ViewChildren'selector不匹配,因此使用'cpxs'的测试组件内部的函数无法被测试 – user2832323

回答

4

可以使用反映的元数据功能来完成它的工作:

it('should have four sons',() => { 
    const propMetadata = Reflect['getMetadata']('propMetadata', FatherComponent); 
    var originType = propMetadata.cpxs[0].selector; 
    propMetadata.cpxs[0].selector = ComplexComponentStub; // Replace ViewChild Type 

    let fixture = TestBed.createComponent(FatherComponent); 

    let comp = fixture.componentInstance as FatherComponent; 
    fixture.detectChanges(); 
    expect(comp.cpxs.length).toBe(4); 

    propMetadata.cpxs[0].selector = originType; // reset ViewChild 
}); 

Test in Plunker

你可以阅读更多关于装饰和反映有关的元数据在这里:

+0

请注意,在Angular 5中,此解决方案似乎不再有效。然而我发现'(MyComponent as any)['__ prop__metadata __']。child [0] .selector = ChildDirectiveMock;'应该可以工作,但它不会是一个非常好的永久解决方案。 – joshhunt

相关问题