I am testing a component which dinamically inserts a checkbox in its template when ngAfterViewInit lifecycle hook is called.
export class MyComponent {
ngAfterViewInit() {
// checkbox insertion in the template here
...
}
...
}
This is my test:
it('should inject the checkbox', () => {
fixture = TestBed.createComponent(AutogeneratedTableComponent);
fixture.detectChanges();
rows = fixture.debugElement.queryAll(By.css('tr'));
console.log(Object.assign({}, rows[1].nativeElement)); // *referenceLog
console.log(rows[1].nativeElement)); // *cloneLog
expect(rows[1].query(By.css('input')).not.toBeNull(); // FAILS
}
*refereceLog (prints the tr without the inserted td)
<tr ng-reflect-id="22" id="22">
<td>Single Room</td>
<td>My single room.</td>
</tr>
*cloneLog (shows that at time of testing the template is not ready)
Object{__zone_symbol__eventTasks: [ZoneTask{zone: ..., runCount: ..., _zoneDelegates: ..., _state: ..., type: ..., source: ..., data: ..., scheduleFn: ..., cancelFn: ..., callback: ..., invoke: ...}]}
I tried manually calling ngAfterViewInit()
it('should inject the checkbox', () => {
fixture = TestBed.createComponent(AutogeneratedTableComponent);
fixture.detectChanges();
fixture.debugElement.componentInstance.ngAfterViewInit();
fixture.detectChanges();
rows = fixture.debugElement.queryAll(By.css('tr'));
console.log(Object.assign({}, rows[1].nativeElement)); // *referenceLog
console.log(rows[1].nativeElement)); // *cloneLog
expect(rows[1].query(By.css('input')).not.toBeNull(); // FAILS
}
*refereceLog (prints the expected tr)
<tr ng-reflect-id="22" id="22">
<td><input id="22" type="checkbox"></td>
<td>Single Room</td>
<td>My single room.</td>
</tr>
No changes in *cloneLog
Then I tried
Adding
spyOn(component, 'ngAfterViewInit').andReturnValue(Promise.resolve(true)).and.callThrough();
and thenspyOn().calls.mostRecent.returnValue.then(() => {fixture.detectChanges() ... })
with thedone()
at the bottom of the blockAdding
async()
to the individual test declaration and doing the evaluation inside afixture.whenStable.then( () => { fixture.detectChanges()... } )
Adding
fakeAsync()
to the individual test declaration and atick()
calling before the evaluation
All the attempts with the same previous result. The template element is being updated after the evaluation is done.
I should find a way to stop the test execution until the nativeElement that I am testing is updated.