在 Jest 测试用例中使用 React Apollo 时“无法读取属性 _location of null”

Dan*_*try 5 javascript react-apollo

给定以下组件:

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

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

export default graphql(Query)(MatchListRouteHandler);
Run Code Online (Sandbox Code Playgroud)

和测试用例:

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

当 Jest 尝试运行测试用例时,我收到以下错误:

/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)
Run Code Online (Sandbox Code Playgroud)

pet*_*and 7

请注意这一点。我今天遇到了这个错误,也是使用 Apollo + Jest,但我以一种可能更优雅的方式修复了这个错误,不确定,但我卸载了在 afterEach 中测试的组件。

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

afterEach(() => {
    wrapper.unmount();
});
Run Code Online (Sandbox Code Playgroud)


Dan*_*try 5

出现这种情况似乎是因为 Jest 测试进程退出得太快;Apollo 尝试在安装应用程序后继续请求您提供的数据,但直到测试结束才会出现响应,从而导致出现此神秘错误消息,从而导致整个 Jest 运行程序退出。

这可以通过在相关测试结束之前人为增加延迟来解决,即:

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

  setTimeout(() => done());
});
Run Code Online (Sandbox Code Playgroud)

请注意,这并不能完全修复错误(实际上,上面的测试总是会通过),但这确实意味着您的整个测试运行程序不会完全崩溃。

正确的答案可能涉及在测试中使用服务器端渲染。

  • 这个答案很糟糕,我后悔写了它。请不要尝试以这种方式对抗竞争条件 - 请参阅彼得的回答。 (13认同)