Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
582 views
in Technique[技术] by (71.8m points)

javascript - How to use Jest __mocks__ to mock react-router-dom in a monorepo

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Instead of mocking, you could use MemoryRouter component as a wrapper to your test component.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...