Search code examples
reactjsjestjsreact-routerreact-router-domenzyme

React Router V6 - useNavigate() may be used only in the context of a <Router> component


I have installed react-router-domV6. I am having the above error when I run my very basic test using Jest-Enzyme:

expect(shallow(<CustomerListTable customers={mockCustomers} />).length).toEqual(1);

I already came across this similar issue mentioned here, but I am already doing the provided answers. Even tried doing the import { BrowserRouter as Router } from "react-router-dom";. What am I missing here?

index.js

import React, { Suspense } from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { StrictMode } from "react";
import { BrowserRouter } from "react-router-dom";
...

ReactDOM.render(
  <StrictMode>
          ...
            <BrowserRouter>
              <AuthProvider>
                <App />
              </AuthProvider>
            </BrowserRouter>
          ...
  </StrictMode>,
  document.getElementById("root")
);

App.js

import React from "react";
import { useRoutes } from "react-router-dom";
import Routing from "./routes";
import useAuth from "./hooks/useAuth";
import { CreateCustomTheme } from "./theme";
import { ThemeProvider } from "@mui/material/styles";
import CssBaseline from "@mui/material/CssBaseline";
import useSettings from "./hooks/useSettings";
import useScrollReset from "./hooks/useScrollReset";
import SplashScreen from "./components/splashScreen/SplashScreen";

const App = () => {
  const content = useRoutes(Routing());
  const { settings } = useSettings();
  const auth = useAuth();

  useScrollReset();

  const theme = CreateCustomTheme({
    direction: settings.direction,
    responsiveFontSizes: settings.responsiveFontSizes,
    roundedCorners: settings.roundedCorners,
    theme: settings.theme,
  });
  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />
      {auth.isInitialized ? content : <SplashScreen />}
    </ThemeProvider>
  );
};

export default App;

Solution

  • It seems the CustomerListTable component you are testing in isolation doesn't have access to a routing context it's expecting as when it's rendered in the app normally. It's completely normal to need to wrap components when testing them with providers (redux, themes/styling, localization, routing, etc...) that are providing specific React Context values the component is accessing, typically via React hooks.

    For the unit test you should wrap the component with the providers it's expecting to have.

    expect(shallow(
      <BrowserRouter>
        <CustomerListTable customers={mockCustomers} />
      </BrowserRouter>
    ).length).toEqual(1);
    

    It's been a long time since I've used Enzyme, so I'm not certain the shallow render will still work, but if it doesn't then swap to the full mount test renderer.