I want to test an Observable
with jasmine-marble testing, but unfortunately I can't figure out how to trigger change detection for ngIf
, which should render the component.
This is a simplified version of my class:
export class MyComponent implements OnInit {
data$: Observable<{data: any[]}>;
constructor(private baseService: BaseService) { }
ngOnInit(): void {
this.data$ = this.baseService.get(endpoint);
}
}
And my html file:
<custom-component *ngIf="data$ | async as value" [data]="value.data">
...
</custom-component>
This is my current test, which fails:
it ('should display custom component', fakeAsync(() => {
const expected = cold('a|', {a: {data: [{id: 1}]}});
baseServiceStub.get.and.returnValue(expected);
component.ngOnInit();
fixture.detectChanges();
tick();
expect(component.data$).toBeObservable(expected); // this passes and the observable also holds the correct value
expect(baseService.get).toHaveBeenCalledWith(endpoint); // this passes aswell
component.data$.subscribe(val => {
console.log(val); // here I can log the correct value of the observable ( {data: [{id:1}]})
});
expect(fixture.debugElement.query(By.css('custom-component'))).not.toBeNull(); // this fails
}));
Unfortunately everything I got is this
Error: Expected null not to be null.
There's no issue with the service or the observable itself, but it seems to me that for some reason the DOM doesn't trigger change detection with the async pipe which would render the component.
PS: When I am using getTestScheduler().flush()
I get the error Can't subscribe to undefined
instead.
I solved it by creating another test suite, where I defined a value for the observable manually. I'm not entirely happy with this approach but it is a workaround for my problem.