最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - Can anyone render react-router-dom components with react-testing-library? - Stack Overflow

programmeradmin2浏览0评论

After a lot of trial and error I cannot get RTL to render any components from react-router-dom. I am using [email protected], @testing-library/[email protected], @testing-library/[email protected], [email protected] and [email protected] (which I have tried upgrading but cannot get my dom to unstick from the [email protected] inbuilt [email protected] even with a number of workaround attempts in setup files).

As far as I can see online these versions should be compatible but I am not even able to render a link component in a test without this error (below). The same error comes up for any other react-router-dom component that I have tried (BrowserRouter and MemoryRouter). The same error appears when trying to import the components from react-router.

The original component I was trying to render (which works when rendering normally i.e. non testing env) =>

import {BrowserRouter, Routes, Route, Link } from "react-router-dom";
import NavBar from './components/NavBar';
import Home from "./Pages/Home.jsx";
// ^ I left these in to show the context of my own use but you can comment these 
// out and put a div in the browser router or leave it empty. I won't be able to 
// add these files in this post.

function App() {
  return (
    <BrowserRouter>
      <NavBar />
      <Routes>
        <Route path="/" element={<Home />} />
      </Routes>
    </BrowserRouter>
  );

}
export default App;

The App itself is rendered within standard index.js =>

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
   <React.StrictMode>
      <App />
   </React.StrictMode>,
);

The test I originally wanted =>

import { render } from '@testing-library/react';
import App from './App';
import React from "react";
import { BrowserRouter, MemoryRouter, Link } from 'react-router-dom';

test('renders App', () => {
  render(<App />); // it fails on this line
  expect(<App />).toBeDefined();
});

The minimal tests for narrowing down the problem source =>

import { render } from '@testing-library/react';
import App from './App';
import React from "react";
import { BrowserRouter, MemoryRouter, Link } from 'react-router-dom';

test('renders BrowserRouter', () => {
  render(<BrowserRouter />);
});

test('renders MemoryRouter', () => {
  render(<MemoryRouter />);
});

// in a function to re-create the context

function TestComponent() {
  return <BrowserRouter></BrowserRouter>;
}

test('renders TestComponent', () => {
  const { container } = render(<TestComponent />); // also failing on this line
  expect(container).toBeDefined();
});

All these tests have the same error type:

output:
console.error
      Error: Uncaught [TypeError: Cannot read properties of null (reading 'useRef')]
Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
      1. You might have mismatching versions of React and the renderer (such as React DOM)
      2. You might be breaking the Rules of Hooks
      3. You might have more than one copy of React in the same app
      See  for tips about how to debug and fix this problem.
console.error
     The above error occurred in the <BrowserRouter> component:
     at fn (/.../packages/react-router-dom/index.tsx:136:3)

The react-router-dom elements never cause any such problems when I run the application outside testing environment so I suspect there is some issue with jest but I have exhausted everything I/internet research could think to try so I'm really hoping anyone can help! If anyone has seen this issue or knows anything about it please let me know.

For more context, these errors do not appear when rendering non-react-router-dom components with hooks in them!

Steps to recreate: Install the same package versions and create the example test above.

What did I try: Tried ensuring no version mismatch, upgrading many packages (to the ones above), adding various settings to package.json to try to use upgraded version of jsdom including trying to explicitly set it as global dom in setupTests.js which did not work..., setting TextEncoders and TextDecoders, and rendering many different variants (React.StrictMode wrapped, using ReactDOM root rendering, putting it inside container, importing from react-router instead of react-router-dom) to see if it was anything in my set up.

After a lot of trial and error I cannot get RTL to render any components from react-router-dom. I am using [email protected], @testing-library/[email protected], @testing-library/[email protected], [email protected] and [email protected] (which I have tried upgrading but cannot get my dom to unstick from the [email protected] inbuilt [email protected] even with a number of workaround attempts in setup files).

As far as I can see online these versions should be compatible but I am not even able to render a link component in a test without this error (below). The same error comes up for any other react-router-dom component that I have tried (BrowserRouter and MemoryRouter). The same error appears when trying to import the components from react-router.

The original component I was trying to render (which works when rendering normally i.e. non testing env) =>

import {BrowserRouter, Routes, Route, Link } from "react-router-dom";
import NavBar from './components/NavBar';
import Home from "./Pages/Home.jsx";
// ^ I left these in to show the context of my own use but you can comment these 
// out and put a div in the browser router or leave it empty. I won't be able to 
// add these files in this post.

function App() {
  return (
    <BrowserRouter>
      <NavBar />
      <Routes>
        <Route path="/" element={<Home />} />
      </Routes>
    </BrowserRouter>
  );

}
export default App;

The App itself is rendered within standard index.js =>

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
   <React.StrictMode>
      <App />
   </React.StrictMode>,
);

The test I originally wanted =>

import { render } from '@testing-library/react';
import App from './App';
import React from "react";
import { BrowserRouter, MemoryRouter, Link } from 'react-router-dom';

test('renders App', () => {
  render(<App />); // it fails on this line
  expect(<App />).toBeDefined();
});

The minimal tests for narrowing down the problem source =>

import { render } from '@testing-library/react';
import App from './App';
import React from "react";
import { BrowserRouter, MemoryRouter, Link } from 'react-router-dom';

test('renders BrowserRouter', () => {
  render(<BrowserRouter />);
});

test('renders MemoryRouter', () => {
  render(<MemoryRouter />);
});

// in a function to re-create the context

function TestComponent() {
  return <BrowserRouter></BrowserRouter>;
}

test('renders TestComponent', () => {
  const { container } = render(<TestComponent />); // also failing on this line
  expect(container).toBeDefined();
});

All these tests have the same error type:

output:
console.error
      Error: Uncaught [TypeError: Cannot read properties of null (reading 'useRef')]
Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
      1. You might have mismatching versions of React and the renderer (such as React DOM)
      2. You might be breaking the Rules of Hooks
      3. You might have more than one copy of React in the same app
      See https://reactjs./link/invalid-hook-call for tips about how to debug and fix this problem.
console.error
     The above error occurred in the <BrowserRouter> component:
     at fn (/.../packages/react-router-dom/index.tsx:136:3)

The react-router-dom elements never cause any such problems when I run the application outside testing environment so I suspect there is some issue with jest but I have exhausted everything I/internet research could think to try so I'm really hoping anyone can help! If anyone has seen this issue or knows anything about it please let me know.

For more context, these errors do not appear when rendering non-react-router-dom components with hooks in them!

Steps to recreate: Install the same package versions and create the example test above.

What did I try: Tried ensuring no version mismatch, upgrading many packages (to the ones above), adding various settings to package.json to try to use upgraded version of jsdom including trying to explicitly set it as global dom in setupTests.js which did not work..., setting TextEncoders and TextDecoders, and rendering many different variants (React.StrictMode wrapped, using ReactDOM root rendering, putting it inside container, importing from react-router instead of react-router-dom) to see if it was anything in my set up.

Share Improve this question asked Mar 11 at 12:55 rdnrdn 11 bronze badge 1
  • Well, as I said in your post in the Staging Ground, React-Router works much the same in unit testing as it does in regular UI files. Here's a running CodeSandbox of the code and dependency versions you provided, and as you can see the unit tests run without issue. Perhaps you have some issue elsewhere. Feel free to fork my sandbox or create one of your own and add more of your actual code/setup/configs/versions/etc. to see if you can reproduce the issue that readers here could then inspect live. – Drew Reese Commented Mar 11 at 15:19
Add a comment  | 

1 Answer 1

Reset to default 0

If anyone else has a similar issue, what I found worked for me is either

  1. Downgrading react-router-dom to any 6.x.x

or

  1. Migrating from Create React App/react-scripts to Vite

There maybe some fiddly workarounds possible with setting global TextEncoders and TextDecoders that I've seen suggested but this didn't work for me.

发布评论

评论列表(0)

  1. 暂无评论