最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin3浏览0评论

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)

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)
Share Improve this question asked May 19, 2017 at 17:11 DanDan 10.5k2 gold badges39 silver badges68 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 8

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();
});

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.

just unmount the created component after rendering like that:

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

  ReactDOM.unmountComponentAtNode(div); // unmounting the created component.
});

unmounting the component should make the error disappears.

@peter.mouland's answer worked for me. Because I was testing that a component could be rendered by ReactDOM, I implemented his approach like this:

describe('<MyComponent />', () => {
  const div = document.createElement('div');

  afterEach(() => {
    ReactDOM.unmountComponentAtNode(div);
  });

  it('deep renders without crashing', () => {
    ReactDOM.render(<MyComponen />,div);
  });
});

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论