Using timeouts in our automated tests? How dare you. π
I admit I did that, but let me explain.
We had this test that was throwing an error, on a component that I did not write:
ReferenceError: You are trying to
import
a file after the Jest environment has been torn down.
The tests were passing, but it was flaky - failing in CI, wasting developer time and CI cycles.
I tried tracking it down, and it said I was importing React's Modal
component. Of course I was, the component itself was a Modal.
This couldn't have been it. I took a step back to really understand what this component was doing, and realized that it depended on multiple asynchronous behaviors. The Jest environment had been torn down, but the component was still trying to do something.
I did my best to play around with fake timers, done callback, and ticks to no avail.
Alas, the solution was simple: explicitly tell Jest to wait, because the test is not over yet.
// Not recommended practice. Use sparingly.
await act(async () => {
return new Promise((resolve) => {
setTimeout(resolve, 1000);
});
});
The tradeoff is, each time your test runs, you "spend one extra second" which costs money. However, the test used to fail after running for multiple minutes! So I think that spending one extra second to save minutes is overall a good tradeoff.
I have more stories to share, especially about the dreaded "You called act(async() => ...)
without await" error so stay tuned.
Top comments (4)
Oh you've just made a quickfix and the actual bug fix will be handled by someone else. Hopefully the trace of this issue will remain somewhere in your bug tracker and that Someone wouldn't stalk you in the night π
Hahah, my manager reviewed the code. I'm still not sure if that's a good thing or a bad thing. If I stop posting, maybe one of my teammates already got to me... π
Found the solution because I got challenged by your comment @vladignatyev . Will write about it later, but basically a modal close was being flushed after Jest tore down, so the fix was just wait for the modal to be closed instead of "wait 1 second"
So, I saved a soul! What a fun! π