We are using
TestBed.overrideComponent(CoolComponent, {
set: {
template: '<div id="fake-component">i am the fake component</div>',
selector: 'our-cool-component',
inputs: [ 'model' ]
}
})
to override a component.
The component has a ViewChild which we configure in our ngOnInit method
@Component({
selector: 'our-cool-component',
templateUrl: 'cool.component.html'
})
export class CoolComponent implements OnInit, OnDestroy {
@Input() model: SomeModel
@ViewChild(CoolChildComponent) coolChildComponent;
ngOnInit() {
this.coolChildComponent.doStuff();
}
}
The CoolComponent
in turn lives in a Wrapper
component.
When we call fixture.detectChanges()
on the Wrapper
fixture, this attempts to construct the CoolComponent, but it immediately dies when it calls doStuff() because CoolChildComponent
is undefined.
Is there a way to get at the CoolComponent
to stub its CoolChildComponent
? It doesn't seem like we can get it off the Wrapper
because it's only referenced through the template, not as a property of the component.
Another thing to note is that TestBed overrides need to happen before .createComponent is called. I tried the .overrideProvider call after .compileComponents and before .createComponent in the 2nd beforeEach, and it still worked fine.
The TestBed injector (acting like NgModule 's injector) and the component's injector. TestBed.get () uses the providers array in configureTestingModule while the componentRef.injector is using the component's injector which uses the component level providers, which is overrode by the set in overrideComponent.
Although the inject example above does the trick, it adds a lot of cruft to the it declarations. Looking at the Angular docs, I found the TestBed has some .overrideX () methods ( .overrideModule, .overrideComponent, etc...).
Just create a mock component with the same selector and use TestBed to remove the declaration of the real child component and add the declaration to your mock component.
ngOnInit() {
this.coolChildComponent.doStuff();
}
should be
ngAfterViewInit() {
this.coolChildComponent.doStuff();
}
because
View child is set before the ngAfterViewInit callback is called.
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