Как использовать Jest __mocks__ для издевательства над react-router-dom в monorepo

#javascript #reactjs #jestjs

#javascript #reactjs #jestjs

Вопрос:

Я не могу издеваться react-router-dom , я вижу ошибку, потому что макет не создается. Где я ошибаюсь?:

У меня есть структура monorepo как таковая, приложения создаются CRA и используются craco в корне:

 |── 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);

 

Если я издеваюсь над зависимостью в spec файле, все работает так, как ожидалось:

 // 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 />);
  });
});
 

Однако я не хочу повторять импорт в нескольких spec файлах, поэтому я смотрю на функцию ручного редактирования Jest: https://jestjs.io/docs/en/manual-mocks

Я изменил структуру папок, чтобы быть:

 |── 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
 

С макетным файлом, содержащим:

 // __mocks__/react-router-dom.js

const reactRouterDom = jest.createMockFromModule("react-router-dom");

reactRouterDom.withRouter = ({ children }) => children;

module.exports = reactRouterDom;

 

И spec файл теперь похож:

 // 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 />);
  });
});
 

Однако при запуске тестов теперь я получаю сообщение об ошибке:

 Invariant failed: You should not use <withRouter(MyComponent) /> outside a <Router>
 

Что указывает мне, что react-router-dom это больше не издевается.

Ответ №1:

Вместо издевательства вы могли бы использовать MemoryRouter component в качестве оболочки для вашего тестового компонента.

Ответ №2:

Я решил это. Проблема заключалась в том, что __mocks__ это не входило в объем проекта jest.config.js roots

roots: ["<rootDir>", "<rootDir>/../../__mocks__"]