Difference between async/await and async/fixture.whenStable in Angular

Viewed 882

I want to know the difference between these two methods for dealing with asynchronous calls in the Angular framework while testing:

  • The first with the jasmine approach async/await
  • The second with the Angular approach async/fixture.whenStable

Are they similar? If not, what is the difference, and when exactly should I use one rather than the other?

1 Answers

The first approach of async/await is stock JavaScript where you want to run the function asynchronously and you can await for promises before carrying over to the next line.

it('it block in an async await way', async(done) => {
   await waitForThisFunctionThatReturnsAPromiseBeforeCarringForward();
   // do something, make assertions
   const x = await getXFromAPromise(); // wait for getXFromAPromise() function to return the promise
// and assign the results to x
   // do something, make assertions
   done(); // call done to ensure you have run through the whole it block and tell Jasmine you're done
});

The fixture.whenStable basically waits for all promises in the stack to be resolved before carrying forward with assertions.

it('demonstration of fixture.whenStable', async(done) => {
   // do some actions that will fire off promises
   await fixture.whenStable(); // wait until all promises in the call stack have been resolved
   // do some more assertions
   done(); // call done to tell Jasmine you're done with this test.
});

The done callback is optional but I use it to ensure for better engineering (make sure it traversed through the whole it block).

Edit ====================

To handle observables, I use two methods.

async/await with take and toPromise operator where you take the first emission and you convert it to a promise. Feel free to add other operators such as filter to ignore some emissions before the take(1).

import { take } from 'rxjs/operators';
......
it('should do xyz', async done => {
  const x = await component.observable$.pipe(take(1)).toPromise();
  expect(x).toBe(....);
  done();
});

The other way is to subscribe with done callback

it('should do xyz', done => {
  component.observable$.subscribe(result => {
    expect(result).toBe(...);
    // call done here to ensure the test made it within the subscribe
    // and did the assertions and to let Jasmine know you're done with the tests
    done();
  });
});
Related