2016-11-29 56 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

相關問題