In an angular application, I use some tools library and some of my code that have:
- Async declaration
- 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.