Home > Blockchain >  How to wait on async method in an angular test?
How to wait on async method in an angular test?

Time:04-12

In an angular application, I use some tools library and some of my code that have:

  1. Async declaration
  2. Use a setInterval inside that I don't want to wait.

I've found this article that shows how to use fakeAsync, flushMicrotask and tick, that seem to do the job, but it doesn't seems to work.

Currently I've this:

  it('should refresh the token in time', fakeAsync(() => {
    //Arrange
    let token = null;
    generateToken().then(result => {
      token = result;
      console.log('Generated token: '   token); //properly displayed
    });
    flushMicrotasks();
    expect(token).not.toBeNull(); //crashes
    //Rest of the test


  }));
});

but it seems the expect is executed before the generateToken method.

(generateToken returns a Promise and basically generate a test token with jose library)

I could use the async declaration in the "it" method, but my understanding is that won't solve my real issue, to accelerate a setInterval

Has the recommended way of testing async code changed? Or what am I missing?

CodePudding user response:

Try this:

it('should refresh the token in time', async(() => {
   //Arrange
   let token = null;
   token = await generateToken();
   expect(token).not.toBeNull(); //crashes
   //Rest of the test
}));

CodePudding user response:

Have you tried tick and flush?

    let token = null;
    generateToken().then(result => {
      token = result;
      console.log('Generated token: '   token); //properly displayed
    });
    tick(2 * 60 * 1000); // move time 2 minutes in a fake way
   
    flush();
    // can also use discardPeriodicTasks(); instead of flush
    expect(token).not.toBeNull();

The tick should move the time 2 minutes in a fake way and the flush should get rid of the setInterval. You can't use flushMicroTrasks() because that will flush microtasks (promises) and not Web APIs like setInterval or setTimeout. Web APIs are macrotasks.

CodePudding user response:

Just await for the result

it('should refresh the token in time', async () =>{
   const token = await generateToken();
   expect(token).not.toBeNull();
});

this way you can serialize code execution.

  • Related