When testing components with <Link>
s, for example in my answer to Recommended approach for route-based tests within routes of react-router, I often use the following pattern to get access to the current location
for testing purposes:
const renderInRouter = () => {
const history = createMemoryHistory();
const wrapper = render(
<Router history={history}>
<MyPage />
</Router>
);
return { ...wrapper, history };
}
This worked fine up to v5.3, but after upgrading to v6 I get:
FAIL ./demo.test.js
✕ works (205 ms)
● works
TypeError: Cannot read properties of undefined (reading 'pathname')
at Router (../packages/react-router/index.tsx:281:5)
...
This use-case isn't covered in the migration docs, v6 has no testing guides so far and, although the API reference does show that the history
prop is no longer expected:
interface RouterProps {
basename?: string;
children?: React.ReactNode;
location: Partial<Location> | string;
navigationType?: NavigationType;
navigator: Navigator;
static?: boolean;
}
it's not clear what the v6 equivalent is; I tried switching to navigator={history}
but still got the same error.
To reproduce, copy the following files into a new directory and run npm install
then npm test
:
package.json
{
"name": "router6-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "jest"
},
"jest": {
"testEnvironment": "jsdom"
},
"babel": {
"presets": [
"@babel/preset-react"
]
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/preset-react": "^7.16.0",
"@testing-library/react": "^12.1.2",
"jest": "^27.3.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^6.0.0"
}
}
index.test.js
:
const { render } = require("@testing-library/react");
const { createMemoryHistory } = require("history");
const React = require("react");
const { Router } = require("react-router-dom");
it("used to work", () => {
render(
<Router history={createMemoryHistory()}></Router>
);
});
If you npm install --save-dev react-router@5
and run npm test
again, you can see that this passes in v5.