Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Cannot read property _location of null" when using React Apollo in a Jest test case

Tags:

Given the following component:

export function App() {
  return withApollo(<BrowserRouter>
    <MatchListRouteHandler />
  </BrowserRouter>);
}

// MatchListRouteHandler
export const Query = addTypenameToDocument(gql`
  query GetMatches {
    matches {
      id
    }
  }
`);

export default graphql(Query)(MatchListRouteHandler);

And the test case:

it('renders without crashing', () => {
  const div = document.createElement('div');
  ReactDOM.render(<App />, div);
});

I get the following error when Jest attempts to run the test case:

/home/dan/match-history-analyser/node_modules/jsdom/lib/jsdom/browser/Window.js:148
      return idlUtils.wrapperForImpl(idlUtils.implForWrapper(window._document)._location);
                                                                              ^

TypeError: Cannot read property '_location' of null
    at Window.get location [as location] (/home/dan/Projects/match-history-analyser/node_modules/jsdom/lib/jsdom/browser/Window.js:148:79)
    at Timeout.callback [as _onTimeout] (/home/dan/Projects/match-history-analyser/node_modules/jsdom/lib/jsdom/browser/Window.js:525:40)
    at ontimeout (timers.js:386:14)
    at tryOnTimeout (timers.js:250:5)
    at Timer.listOnTimeout (timers.js:214:5)
like image 835
Dan Avatar asked May 19 '17 17:05

Dan


2 Answers

This seems to occur because the Jest test process exits too quickly; Apollo attempts to continue to request the data you've provided after the App was mounted, but the response doesn't occur until after the test has ended, leading to this cryptic error message which causes the entire Jest runner to quit.

This can be remedied by artificially increasing the delay before the test in question ends, ie:

it('renders without crashing', (done) => {
  const div = document.createElement('div');
  ReactDOM.render(<App />, div);

  setTimeout(() => done());
});

Note that this does not fix the error entirely (actually, your test above will always pass), but it does mean that your entire test runner will not completely bomb out.

The correct answer probably involves using Server Side Rendering in your tests.

like image 112
Dan Avatar answered Sep 22 '22 10:09

Dan


Just a note on this. I came across this error today, also with Apollo + Jest but I fixed in in what might be a more elegant way, not sure, but I unmounted the components being tested in an afterEach.

beforeEach(() => {
    wrapper = mount(<Root location={ '/route/' } context={context} />);
})

afterEach(() => {
    wrapper.unmount();
});
like image 37
peter.mouland Avatar answered Sep 22 '22 10:09

peter.mouland