2016-11-29 42 views
5

Załóżmy, że mam składnik, który chcę przetestować, i który używa bardzo złożonego komponentu. Ponadto wywołuje niektóre ze swoich metod, korzystając z referencji uzyskanych przez @viewChildren. Na przykład:Jak wymienić komponent użyty w @viewChildren na podwójny test?

@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> 
    // .... 
    } 

Jak mogę zamienić złożony komponent dla podwójnego testu w `TestBed '?

Coś

@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); 
}); 

    //.... 
})); 

Aby uzyskać pełną przykład patrz plnkr http://plnkr.co/edit/ybdrN8VimzktiDCTvhwe?p=preview

+1

nie jestem pewien, że jest to dobry sposób, ale można sprawdzić to plunker https: // plnkr. co/edit/1w04DDKnYQ7kH6tIE0pK? p = preview – yurzui

+0

Wielkie dzięki, to działa – user2832323

+0

Jednak "cpxs" wydaje się pusty w moich testach ... Podwójne są skutecznie tworzone, ale lista '@ ViewChildren'selector nie będzie pasować, i dlatego funkcje wewnątrz komponentu testowego, które używają 'cpxs't nie mogą być testowane – user2832323

Odpowiedz

4

Można użyć odzwierciedlać-Metadane możliwości zrobić to działa:

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

Możesz przeczytać więcej o dekoratorów i około odzwierciedlać-metadane tutaj:

+0

Należy zauważyć, że w Angular 5 rozwiązanie to nie działa. Jednak odkryłem, że '(MyComponent jak każdy) ['__ prop__metadata __']. Child [0] .selector = ChildDirectiveMock;' powinno działać, ale nie wydaje się być dobrym, trwałym rozwiązaniem. – joshhunt