DEV Community

Lem
Lem

Posted on

Pushing Anti-patterns to Production for Fun and Profit

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);
    });
  });
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
vladignatyev profile image
Vladimir Ignatev

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 πŸ˜‚

Collapse
 
bytehala profile image
Lem

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... πŸ˜‚

Collapse
 
bytehala profile image
Lem • Edited

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"

await waitFor(() =>
  expect(getByTestId("SelectModal").props).toHaveProperty(
    "visible",
    false,
  ),
);
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
vladignatyev profile image
Vladimir Ignatev • Edited

So, I saved a soul! What a fun! πŸ˜‚