This is my stackblitz example where you can see in the terminal the test running and its result (or you can stop the execution and run jest
).
I use the NgrxLet directive to consume the resulting observables in my components, like this:
myComponent.component.html
<ng-container *ngrxLet="myObs$ as myObs">
<p> {{ myObs }} </p>
</ng-container>
myComponent.component.ts
@Component({
selector: 'my-component',
standalone: true,
imports: [CommonModule, LetDirective],
templateUrl: './my-component.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MyComponent implements OnInit {
myObs$: Observable<string> = of('');
myObsService = inject(MyObsService);
ngOnInit() {
this.myObs$ = this.myObsService.myObs$;
}
}
However this creates an odd situation where the content of the ng-container *ngrxLet="myObs$ as myObs"
never renders in my jest unit tests, even though this works perfectly during the execution.
I've tried a few solutions I could think of after going through Angular's component testing documentation :
const myObscontent = 'myObs content';
describe('myComponent tests', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [LetDirective, MyComponent],
providers: [
{ provide: MyObsService, useValue: {myObs$: of(myObsContent)}},
],
}).compileComponents();
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
})
it('should show myObs content', async () => {
await fixture.whenStable();
expect(fixture.debugElement.nativeElement.textContent.includes(myObsContent))
.toBeTruthy();
})
})
👆 the rendered version never contains myObs content
.
I've also tried using fakeAsync
instead of async
, and creating a behaviorSubject
then pushing my observable value, to replace the cold observable created by of
in my example above by a hot one.
The result in all the scenarios is that whatever lives inside of the ng-container *ngrxLet="myObs$ as myObs"
and consumes myObs
never renders.
is there any documentation about testing with Ngrx's LetDirective?
what are the alternatives?
Try fixture.whenStable
, which strangely does not work with await
but works great with .then(() => { ... });
syntax:
it('should show the fact', (done) => {
const staticText = 'outside of ngrxlet ng containerCat Fact: ';
fixture.whenStable().then(() => {
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.textContent).toContain(`${staticText}${catFact}`);
done();
});
});