Reputation: 1513
I am unable to mock react-router-dom
, I am seeing an error because the mock isn't being instansiated. Where am I going wrong?:
I have a monorepo structured as such, apps are created with CRA
and use craco
at the root:
|── node_modules
└── applications
|── myFirstApp
| └── src
| └── components
| └── MyComponent.js
| └── MyComponent.spec.js
|── mySecondApp
| └── src
| └── components
| └── MyComponent.js
| └── MyComponent.spec.js
└── myThirdApp
└── src
└── components
└── MyComponent.js
└── MyComponent.spec.js
// applications/myFirstApp/src/components/MyComponent.js
import React from "react";
import { withRouter } from "react-router-dom";
class NavigationProviderBase extends Component {
render() {
return (
*foo*
);
}
}
export default withRouter(NavigationProviderBase);
If I mock the dependency in the spec
file everything works as expected:
// applications/myFirstApp/src/components/MyComponent.spec.js
import { render } from "@testing-library/react";
import React from "react";
import MyComponent from "./MyComponent";
jest.mock("react-router-dom", () => ({
withRouter: (component) => component,
}));
describe("MyComponent", () => {
it("should do stuff", () => {
render(<MyComponent />);
});
});
However, I don't want to be repeating the import in multiple spec
files so I am looking at Jest's manual mocking feature: https://jestjs.io/docs/en/manual-mocks
I have changed my folder structure to be:
|── node_modules
|── __mocks__
| └── react-router-dom.js
└── applications
|── myFirstApp
| └── src
| └── components
| └── MyComponent.js
| └── MyComponent.spec.js
|── mySecondApp
| └── src
| └── components
| └── MyComponent.js
| └── MyComponent.spec.js
└── myThirdApp
└── src
└── components
└── MyComponent.js
└── MyComponent.spec.js
With the mock file containing:
// __mocks__/react-router-dom.js
const reactRouterDom = jest.createMockFromModule("react-router-dom");
reactRouterDom.withRouter = ({ children }) => children;
module.exports = reactRouterDom;
And the spec
file now like:
// applications/myFirstApp/src/components/MyComponent.spec.js
import { render } from "@testing-library/react";
import React from "react";
import MyComponent from "./MyComponent";
describe("MyComponent", () => {
it("should do stuff", () => {
render(<MyComponent />);
});
});
However, when running the tests now I receive the error:
Invariant failed: You should not use <withRouter(MyComponent) /> outside a <Router>
Which indicates to me that react-router-dom
is no longer being mocked.
Upvotes: 3
Views: 2047
Reputation: 1513
I have solved it. The problem was that __mocks__
wasn't in scope in the project jest.config.js
roots
roots: ["<rootDir>", "<rootDir>/../../__mocks__"]
Upvotes: 2
Reputation: 1242
Instead of mocking, you could use MemoryRouter
component as a wrapper to your test component.
Upvotes: 1