'Mocking federated modules in host application for jest

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.

Any recommendation highly appreciated.

Update:

Jest offer virtual mocking and it solves my 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.

Hope it helps whoever struggled same issue.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source