Did you forget to wait something async in your test?

vnglst

Koen van Gilst

Posted on November 19, 2021

Did you forget to wait something async in your test?

Attempted to log “TypeError: Cannot read properties of null (reading ‘URL’)

It’s one of those dreaded, time consuming flaky errors that everyone working with Jest has had to deal with.

The first part of the error is quite clear. Apparently there was still something going on after my test has finished. But what? Problem with this particular error was that it didn’t happen every time (so timing issue?) and it was generally logged after all my tests had run. So, no clue which test was causing it.

The full stacktrace was:

    Attempted to log "TypeError: Cannot read properties of null (reading 'URL')
        at Object.exports.setup (src/node_modules/jsdom/lib/jsdom/living/generated/XMLHttpRequest.js:62:12)
        at new XMLHttpRequest (src/node_modules/jsdom/lib/jsdom/living/generated/XMLHttpRequest.js:101:22)
        at dispatchXhrRequest (src/node_modules/axios/lib/adapters/xhr.js:44:19)
        at new Promise (<anonymous>)
        at xhrAdapter (src/node_modules/axios/lib/adapters/xhr.js:24:10)
        at dispatchRequest (src/node_modules/axios/lib/core/dispatchRequest.js:46:10)
        at Object.defaultQueryFn [as queryFn] (src/src/providers/queryClient.ts:19:7)".
Enter fullscreen mode Exit fullscreen mode

As often with these errors the cause was pretty simple and the solution even simpler.

I’m using React-Query for my api requests, which is a fantastic tool that offers so many functionalities out of the box. One of its features is the prefetching data you know a user is gonna need.

And that’s what I recently added. After the page had fully loaded the frontend starts prefetching some of the other options in a dropdown, so that when the user selects one of the other options the results are there instantly!

Problem was that in some tests these prefetching calls where still running after the test has finished.

In my setupTests.ts file I have the following call to start with a new React Query slate for every test:

afterEach(() => {
  queryClient.clear()
})
Enter fullscreen mode Exit fullscreen mode

Which is great if you want test isolation, but in this case it was causing errors, because the prefetching calls where still running when the query client got cleared.

The solution to this problem is simple and effective:

afterEach(async () => {
    await queryClient.cancelQueries();  queryClient.clear();
});
Enter fullscreen mode Exit fullscreen mode

After every test this will first cancel any queries that are still running and then clear the queryClient.

Problem solved!

💖 💪 🙅 🚩
vnglst
Koen van Gilst

Posted on November 19, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related