jscutlery/devkit

swc-angular-preset: fakeAsync support

jimdubbs opened this issue ยท 5 comments

Excited to try out this preset as jest performance has been a major pain point for our company, thanks for this!

The only issue I've run into so far is when running a spec that uses fakeAsync throws an error:

image

I have confirmed this spec is indeed running in within fakeAsync.

Hey @jimdubbs, I've tested with fakeAsync and tick but I'm not able to reproduce, could you give us more context like a complete code example or a reproduction, please?

My apologies, this seems to be a core angular issue. We use @testing-library/angular with our jest tests, so all of our it() blocks have async functions to await the rendering of the component. When wrapping that async function in fakeAsync(), we see this error occur. I believe this is likely an antipattern on our side. It is interesting though that using jest-preset-angular it doesnt fail.

Great, I'll close this now, feel free to reopen or comment if you need something.

We use @testing-library/angular with our jest tests, so all of our it() blocks have async functions to await the rendering of the component.

Oh! That was the missing information in the first issue's description ๐Ÿ˜Š.

Here is what happens

fakeAsync relies on Zone.js which monkey patches promises so it doesn't work with async / await except if we transform async/await is into generators by target ES2016 or below or simply enabling that transform (luckily we can do the later with swc).

Actually, the other side effect is that microtasks scheduled using async/await are not caught by zone.js which do not trigger a tick and thus CD.
Until we go zoneless, we need this workaround.

Solution

We'll simply enable transform-async-to-generator transform right now ๐Ÿ˜Š

Observation

In order to be zoneless-ready and also avoid the framework-specific cognitive load of fakeAsync + tick, I'd recommend using Jest's fake timers and their async APIs:

(interestingly, Vitest has the same API)