Angular 5 testing: how to get a reference to the child component

前端 未结 3 1751
隐瞒了意图╮
隐瞒了意图╮ 2020-12-24 12:06

I\'m trying to test the interaction between a host component and a child component in an Angular application. I don\'t know how to get a reference to the child component c

相关标签:
3条回答
  • 2020-12-24 12:42

    As explained in the guide, host component instance is created with TestBed.createComponent, and child component instance can be selected from debugElement with By helper:

    childDebugElement = hostFixture.debugElement.query(By.directive(ChildComponent));
    

    Or:

    childDebugElement = hostFixture.debugElement.query(By.css('child'));
    
    0 讨论(0)
  • 2020-12-24 12:56

    Iterate through the childNodes of the debugElement(s) and access the context property to get access to the component ant its properties

    let debugElement = hostFixture.debugElement.childNodes[x] as DebugElement
    debugElement = debugElement.childNodes[x] as DebugElement
    ...
    let component = debugElement.context as YourComponent
    

    This is a very static approach because if a new child is added then maybe you access the wrong childNode. It is better to write a helper method which traverse through the childNodes and find the right name.

    0 讨论(0)
  • 2020-12-24 12:59

    The answer above is good, answers the body's question, but the header/title of the question asks something else. I wanted to answer the question posed by the header as well. Estus's answer is correct for the specific use case, but Google brings you here based on the question in the title.

    To get the child Component not the native element:

    Test Component (called HostComponent in the question): <child [data]="model" #child></child>

    Then in the class definition:

    @Component({template: `<child #child [data]="model"></child>`})
    class HostComponent {
        public model:any;
        @ViewChild('child') child;
    }
    

    Finally, when testing, on a spec:

    it('should do something', () => {
        component.child.value
        component.child.method
        // etc.
    }
    

    You could use this in a test case, and I do, to find the child component that you're really trying to test.


    The rest is to satisfy a debatable aspect brought up in the comments.

    There's also a strong case for making things private when possible. I'm not sure how I feel about it if you want to unit test it. If you want to test a private member you have to let the typescript compiler that you want object with private members publicly accessible by casting it as and wrapping it in parentheses to make it clear what you're casting.

    In the component:

    ...
        @ViewChild('child') private child;
    ...
    

    In the test:

    ...
        (<any>component).child.value
        (<any>component).child.method
    ...
    
    0 讨论(0)
提交回复
热议问题