10

Currently I am trying to test a child component which is accepting an input from the host component, and used within the ngOnInit life cycle hook like the code below.

@Component({
   selector: 'my-child-component',
   template: '<div></div>'
})
class ChildComponent implements OnInit {
    @Input() myValue: MyObject;
    transformedValue: SomeOtherObject;

    ngOnInit():void {
        // Do some data transform requiring myValue
        transformedValue = ...;
    }
}

@Component({
    template:`<my-child-component [myValue]="someValue"></my-child-component>`
})
class HostComponent {
    someValue: MyObject = new MyObject(); // how it is initialized it is not important.
}

How should the ChildComponent be tested in this case where myValue needs the to be present upon creation while being able to have access to ChildComponent.transformedValue for assertion.

I tried creating the ChildComponent using the Angular TestBed class like this

componentFixture = testBed.createComponent(LoginFormComponent)

however the ngOnInit would have already been called up to the point where I call

fixture.componentInstance.myValue = someValue;

I also tried creating a fixture of the HostComponent, and while that works, I got stuck at getting access to the ChildComponent instance that was created, which i require to perform assertions on the ChildComponent.transformedValue field.

Help is greatly appreciated!

Thanks a lot!

Kim Kern
  • 54,283
  • 17
  • 197
  • 195
JeanPaul A.
  • 3,613
  • 1
  • 20
  • 29
  • 1
    If you change the `@Input` value it will trigger the `ngOnChanges` life-cycle so this question might be useful:http://stackoverflow.com/questions/37408801/testing-ngonchanges-lifecycle-hook-in-angular-2 – eko Nov 25 '16 at 09:35
  • 1
    Thanks for the reply! In fact the answer that was given is exactly like the answer which I've posted below regarding how I managed to get access to the child component from the test component. Thanks for sharing though! :) – JeanPaul A. Nov 25 '16 at 09:45

1 Answers1

3

Angular offers the ability to inject children components to their parent components using the @ViewChild() decorator. See https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-view-child

By updating the TestHostcomponent (that is written within the .spec.ts file) to the following

@Component({
    template:`<my-child-component [myValue]="someValue"></my-child-component>`
})
class TestHostComponent {
    @ViewChild(MyChildComponent)
    childComponent: MyChildComponent;
}

it exposes its child component instance ( and its variables ), making the assertion of the 'transformedValue' possible, as per below.

componentFixture = testBed.createComponent(TestHostComponent)
expect(componentFixture.componentInstance.childComponent.transformedValue).toEqual(...someValue);
JeanPaul A.
  • 3,613
  • 1
  • 20
  • 29