14

Question is exactly same here in fact but has different context: How to mock not installed npm package in jest?

I am part of a project where new Module Federation is used from webpack. Basically, I have a host app and it uses remote apps. I am doing the same thing here for the routing: https://github.com/module-federation/module-federation-examples/tree/master/shared-routes2

My host app importing the remote apps' route as similar (I took this example from module-federation repo: https://github.com/module-federation/module-federation-examples/blob/master/shared-routes2/app1/src/App.js)

// app1/src/App.js

import React from "react";
import { BrowserRouter, Route, Switch } from "react-router-dom";


import localRoutes from "./routes";
import remoteRoutes from "app2/routes";

const routes = [...localRoutes, ...remoteRoutes];

const App = () => (
  <BrowserRouter>
    <div data-test-id="App-navigation">
      <h1>App 1</h1>
      <React.Suspense fallback={<div>Loading...</div>}>
        <Switch>
          {routes.map((route) => (
            <Route
              key={route.path}
              path={route.path}
              component={route.component}
              exact={route.exact}
            />
          ))}
        </Switch>
      </React.Suspense>
    </div>
  </BrowserRouter>
);

and my test file for this component look like this:

// app1/src/App.test.js

import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import { render } from '@testing-library/react';

import App from './App';

jest.mock('app2/routes');

describe('App', () => {
  test('should render navigation', async () => {
    const { findByTestId } = render(
      <MemoryRouter>
        <App />
      </MemoryRouter>,
    );
    const app = await findByTestId('App-navigation');

    expect(drawerMenu).toBeInTheDocument();
  });
});

this test produce the error as is:

❯ yarn test App.test.js
yarn run v1.22.10
$ jest App.test.js
 FAIL  src/App.test.js
  ● Test suite failed to run

    Cannot find module 'app2/routes' from 'src/App.test.js'

       6 | import App from './App';
       7 |
    >  8 | jest.mock('app2/routes');
         |      ^
       9 |

      at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:306:11)
      at Object.<anonymous> (src/App.test.js:8:6)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        3.78 s
Ran all test suites matching /App.test.js/i.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

I believe this error occurs because there is actually no module named app2/routes. It's a federated module produced by webpack module federation plugin. However, jest looks for the actual module before mocks it.

This is the part I am stuck and out of ideas.

vvvvv
  • 25,404
  • 19
  • 49
  • 81
Halil Kayer
  • 350
  • 3
  • 8
  • 1
    for a general strategy. I created `remote-apps` folder on inside my `tests` folder and put the mocks in it and structured it with folders by name of remote-apps: `tests > remote-apps > remote-app-A.js` and I put these mock folders inside my `jest.config.js` as `setupFilesAfterEnv` as follows `setupFilesAfterEnv: [ '@testing-library/jest-dom/extend-expect', './tests/remote-apps/remote-app-A.js']` – Halil Kayer Feb 27 '21 at 21:46
  • I just implemented what you suggested but it still throws the same error. Could you help what did you do to resolve it in detail ? You can help me for this : https://stackoverflow.com/questions/72909100/how-to-test-one-micro-front-end-component-in-which-other-micro-frontend-componen – micronyks Jul 11 '22 at 05:01
  • 2
    For future visitors, @micronyks found his own solution here: https://stackoverflow.com/a/72936395/5018572 Long story short. put your `jest.mock` expressions top of your file, below your `import`s – Halil Kayer Jul 13 '22 at 16:11

1 Answers1

1

Jest offer virtual mocking and it solves the issue. (I found the solution out of this answer: https://stackoverflow.com/a/56052635/5018572)

jest.mock('app2/routes', 
  () => { 
    // some mocking for my remote app routes
  },
  { virtual: true }
);

after you make the mocking factory, you simply pass { virtual: true } options and jest stop complaining about the module's existence.


This answer was posted as an edit to the question Mocking federated modules in host application for jest by the OP Halil Kayer under CC BY-SA 4.0.

vvvvv
  • 25,404
  • 19
  • 49
  • 81