Angular Material provides component harnesses for testing, which lets you interact with their components by await
ing promises, like this:
it('should click button', async () => {
const matButton = await loader.getHarness(MatButtonHarness);
await matButton.click();
expect(...);
});
But what if the button click triggers a delayed operation? Normally I would use fakeAsync()
/tick()
to handle it:
it('should click button', fakeAsync(() => {
mockService.load.and.returnValue(of(mockResults).pipe(delay(1000)));
// click button
tick(1000);
fixture.detectChanges();
expect(...);
}));
But is there any way I can do both in the same test?
Wrapping the async
function inside fakeAsync()
gives me "Error: The code should be running in the fakeAsync zone to call this function", presumably because once it finishes an await
, it's no longer in the same function I passed to fakeAsync()
.
Do I need to do something like this -- starting a fakeAsync function after the await? Or is there a more elegant way?
it('should click button', async () => {
mockService.load.and.returnValue(of(mockResults).pipe(delay(1000)));
const matButton = await loader.getHarness(MatButtonHarness);
fakeAsync(async () => {
// not awaiting click here, so I can tick() first
const click = matButton.click();
tick(1000);
fixture.detectChanges();
await click;
expect(...);
})();
});