apollographql / apollo-client

:rocket:  A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
https://apollographql.com/client
MIT License
19.37k stars 2.66k forks source link

“Cannot read property _location of null” when testing with Jest and react-testing-library #12107

Open tom-searle opened 21 hours ago

tom-searle commented 21 hours ago

I am encountering this issue intermittently but regularly when testing my NextJS React application using Jest and react-testing-library. Tests are randomly failing with the error:

"Cannot read property _location of null"

This happens, I believe, because the Jest test process exits too quickly relative to what Apollo is doing, but I confess my understanding of this is a bit lacking.

I would appreciate any guidance on the issue and how I can resolve it! I have provided an example of how I am using Apollo as part of a custom render function in my tests.

Thanks in advance

Example:

import { ApolloClient, ApolloProvider, InMemoryCache } from '@apollo/client';
import { RenderOptions, render } from '@testing-library/react';
import { MemoryRouterProvider } from 'next-router-mock/MemoryRouterProvider';
import { ReactElement } from 'react';

const generateMockClient = () =>
  new ApolloClient({
    uri: process.env.NEXT_PUBLIC_GRAPHQL_API_URL,
    cache: new InMemoryCache(),
    defaultOptions: {
      watchQuery: {
        errorPolicy: 'ignore',
      },
      query: {
        errorPolicy: 'all',
      },
    },
  });

const AllTheProviders = ({ children }: { children: React.ReactNode }) => {
  return (
    <MemoryRouterProvider>
      <ApolloProvider client={generateMockClient()}>{children}</ApolloProvider>
    </MemoryRouterProvider>
  );
};

const customRender = (ui: ReactElement, options?: Omit<RenderOptions, 'wrapper'>) => {
  return render(ui, { wrapper: AllTheProviders, ...options });
};

export * from '@testing-library/react';
export { customRender as render };

and then run a test:

describe('Feature', () => {
  it('does something', async () => {
    render(<MyFeature />);
    const text = screen.getByText('My text');

    expect(text).toBeVisible();
  });
});
phryneas commented 21 hours ago

There's nothing about a _location property in the Apollo Client sources, so I feel like this is probably not an Apollo Client related problem.

Nonetheless, could you please share the full error message with the full stack? Maybe I can point you in the right direction.

tom-searle commented 21 hours ago

Hi @phryneas I appreciate your help!

Here is the full stack trace:

[2024-10-28T15:59:43.700Z] /mnt/workspace/workspace/frontend_main@2/node_modules/@apollo/client/errors/errors.cjs:33

[2024-10-28T15:59:43.700Z]         var _this = _super.call(this, errorMessage) || this;

[2024-10-28T15:59:43.700Z]                            ^

[2024-10-28T15:59:43.700Z] 

[2024-10-28T15:59:43.700Z] ApolloError: Cannot read properties of null (reading '_location')

[2024-10-28T15:59:43.700Z]     at new ApolloError (/mnt/workspace/workspace/frontend_main@2/node_modules/@apollo/client/errors/index.js:39:28)

[2024-10-28T15:59:43.700Z]     at Object.error (/mnt/workspace/workspace/frontend_main@2/node_modules/@apollo/client/core/QueryManager.js:178:84)

[2024-10-28T15:59:43.700Z]     at notifySubscription (/mnt/workspace/workspace/frontend_main@2/node_modules/zen-observable/lib/Observable.js:140:18)

[2024-10-28T15:59:43.700Z]     at onNotify (/mnt/workspace/workspace/frontend_main@2/node_modules/zen-observable/lib/Observable.js:179:3)

[2024-10-28T15:59:43.700Z]     at SubscriptionObserver.error (/mnt/workspace/workspace/frontend_main@2/node_modules/zen-observable/lib/Observable.js:240:7)

[2024-10-28T15:59:43.700Z]     at Object.error (/mnt/workspace/workspace/frontend_main@2/node_modules/@apollo/client/utilities/observables/asyncMap.js:27:34)

[2024-10-28T15:59:43.700Z]     at notifySubscription (/mnt/workspace/workspace/frontend_main@2/node_modules/zen-observable/lib/Observable.js:140:18)

[2024-10-28T15:59:43.700Z]     at onNotify (/mnt/workspace/workspace/frontend_main@2/node_modules/zen-observable/lib/Observable.js:179:3)

[2024-10-28T15:59:43.700Z]     at SubscriptionObserver.error (/mnt/workspace/workspace/frontend_main@2/node_modules/zen-observable/lib/Observable.js:240:7)

[2024-10-28T15:59:43.700Z]     at /mnt/workspace/workspace/frontend_main@2/node_modules/@apollo/client/utilities/observables/iteration.js:7:68

[2024-10-28T15:59:43.700Z]     at Array.forEach (<anonymous>)

[2024-10-28T15:59:43.700Z]     at iterateObserversSafely (/mnt/workspace/workspace/frontend_main@2/node_modules/@apollo/client/utilities/observables/iteration.js:7:25)

[2024-10-28T15:59:43.700Z]     at Object.error (/mnt/workspace/workspace/frontend_main@2/node_modules/@apollo/client/utilities/observables/Concast.js:76:21)

[2024-10-28T15:59:43.700Z]     at notifySubscription (/mnt/workspace/workspace/frontend_main@2/node_modules/zen-observable/lib/Observable.js:140:18)

[2024-10-28T15:59:43.700Z]     at onNotify (/mnt/workspace/workspace/frontend_main@2/node_modules/zen-observable/lib/Observable.js:179:3)

[2024-10-28T15:59:43.700Z]     at SubscriptionObserver.error (/mnt/workspace/workspace/frontend_main@2/node_modules/zen-observable/lib/Observable.js:240:7)

[2024-10-28T15:59:43.700Z]     at handleError (/mnt/workspace/workspace/frontend_main@2/node_modules/@apollo/client/link/http/parseAndCheckHttpResponse.js:167:14)

[2024-10-28T15:59:43.700Z]     at /mnt/workspace/workspace/frontend_main@2/node_modules/@apollo/client/link/http/createHttpLink.js:145:17 {

[2024-10-28T15:59:43.700Z]   graphQLErrors: [],

[2024-10-28T15:59:43.700Z]   protocolErrors: [],

[2024-10-28T15:59:43.700Z]   clientErrors: [],

[2024-10-28T15:59:43.700Z]   networkError: TypeError: Cannot read properties of null (reading '_location')

[2024-10-28T15:59:43.700Z]       at Window.get location [as location] (/mnt/workspace/workspace/frontend_main@2/node_modules/jsdom/lib/jsdom/browser/Window.js:376:79)

[2024-10-28T15:59:43.700Z]       at FetchInterceptor.<anonymous> (/mnt/workspace/workspace/frontend_main@2/node_modules/@mswjs/interceptors/src/interceptors/fetch/index.ts:52:9)

[2024-10-28T15:59:43.700Z]       at step (/mnt/workspace/workspace/frontend_main@2/node_modules/@mswjs/interceptors/lib/interceptors/fetch/index.js:59:23)

[2024-10-28T15:59:43.700Z]       at Object.next (/mnt/workspace/workspace/frontend_main@2/node_modules/@mswjs/interceptors/lib/interceptors/fetch/index.js:40:53)

[2024-10-28T15:59:43.700Z]       at fulfilled (/mnt/workspace/workspace/frontend_main@2/node_modules/@mswjs/interceptors/lib/interceptors/fetch/index.js:31:58),

[2024-10-28T15:59:43.700Z]   extraInfo: undefined

[2024-10-28T15:59:43.700Z] }

I hope that's readable!

phryneas commented 21 hours ago

That seems to be coming somewhere out of msw. I would suggest asking over there if anything is known there.