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!
This is a life cycle hook called by Angular to indicate that the component has been completed. All initialization/declaration should be done with this method. Because the component will be initialized at this point. We simply added the console.log statement in ngOnInit for the parent and child component. Now let’s see the output.
When developing an Angular (read Angular 2 or Angular 4, or whatever the current version is when you read this) component that takes an input, you might decide to unit test the whole component. At least I hope you do! For example, we have a component, ComponentUnderTest, in which we want to display upcased input…
There are a few who only execute once after component initialization. All lifecycle methods are available from @angular/core. Although not required, Angular recommends implementing every hook. This practice leads to better error messages regarding the component.
setInput () sets the input in our host component. Assigning the input in our test before we let Angular detect the changes allows both our tests to pass.. Now, imagine we have to bind not only one but multiple inputs to our component.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With