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)
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 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();
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With