Pushing Anti-patterns to Production for Fun and Profit

Lem - Nov 23 '23 - - Dev Community

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.

. . . . . .
Terabox Video Player