Angular has various ways to handle asynchronous scenarios when testing your code (be it with Karma or Jest).
In this lesson we are specifically looking at the deprecated "async" exported from "@angular/core/testing", which has been replaced by the waitForAsync. Given that, one might also wonder, why not use the async/await statement that is native to Angular. Let's explore!
Juri Strumpflohner: [0:00] I have seen code where the async statement is being used, exported by @angular∕core∕testing. As you can see, the async statement has been deprecated in Angular version 11 and will be removed with Angular version 12.
[0:14] The recommended alternative here is waitForAsync. Let's change this to waitForAsync. This works the same way, so this is a direct replacement. The only reason why the previous async exported by @angular∕core∕testing has been deprecated is because it might cause confusion in people compared to the actual async∕await statement that is native to JavaScript.
[0:36] What we could do here, for instance, is we could just remove the waitForAsync and turn it into the actual async∕await statement being native in JavaScript. What is the main difference? Here, we have perfect control over the whole scenario, so that await∕async is just a nicer syntactic way to handle promises and asynchronous execution.
[1:00] Here for instance, the compiled component returns a promise. We want to make sure that we don't continue the execution until that promise has resolved. The await statement here allows us to wait for that promise to be resolved and then continues, and async is then used in order to tell JavaScript, "Look, this is an async function, so make sure you properly handle that scenario."
[1:24] When should I use the waitForAsync versus just a native async∕await statement? The main question is, where do you have full control over async operations? Here in the TestBed, we know this is the only async call that is being made, and so we can definitely use async∕await.
[1:39] There might however be other situations within your specific test cases where you invoke a component, where you invoke a method call on a component or a service that internally triggers other calls like HTTP calls or timeouts, which you don't have any control over.
[1:55] You cannot use the async∕await statement there, but rather, what you can do is you can use waitForAsync in those scenarios, wrap your entire test case into that waitForAsync, and that would actually then use zone to trigger and handle all async tasks that might happen within that actual invocation.
[2:15] That will make sure to wait properly and to not have a test case that is flawed, because it runs through because it has asynchronous operations, and that always succeeds.
[2:26] To be sure, think about where you can handle all the async scenarios within your test case. If that's the case, use async/await. We are sure and safe to use that for the [inaudible] testing module.
[2:39] If you have doubts within your test cases that some internal callbacks might result into asynchronous operations, you can always fall back to the waitForAsync.