React 测试库不适用于 React Router v6

React testing library not work with react router v6

我几天前开始学习反应测试库,但我不知道如何让我的测试与反应路由器 v6 一起工作。我在下面有这两个测试:

  describe('testing login page', () => {
  test('veryfy inputs and buttons in login page', () => {
    render(
      <MemoryRouter initialEntries={['/']}>
        <Routes>
          <Route path="/" element={<LoginPage />} />
        </Routes>
      </MemoryRouter>,
    );
    const userInput = screen.getByRole('textbox');
    expect(userInput).toBeInTheDocument();
  describe('testing Mine Page', () => {
  test('check table components', () => {
    render(
      <MemoryRouter initialEntries={['/mina']}>
        <Routes>
          <Route path="/mina" element={<MineTable />} />
        </Routes>
      </MemoryRouter>,
    );
    const pageTitle = screen.getByRole('heading', { name: /mina/i });
    expect(pageTitle).toBeInTheDocument();
  });

只有第一个测试有效,第二个不渲染页面MineTable,一直渲染最后一个页面登录。就像第一次测试渲染的历史一样。有人可以帮助我吗?我想测试我的应用程序的每个页面组件。

因为似乎 MineTable 使用了 useNavigate 钩子,所以它需要在它被渲染到的 ReactTree 中更高层提供路由上下文。

您只需要提供路由上下文,无需渲染路由等。为此,您可以直接使用 MemoryRouter.

包装被测组件
describe('testing Mine Page', () => {
  test('check table components', () => {
    render(
      <MemoryRouter>
        <MineTable />
      </MemoryRouter>,
    );
    const pageTitle = screen.getByRole('heading', { name: /mina/i });
    expect(pageTitle).toBeInTheDocument();
  });
});

事实上,这种需要提供上下文的模式非常普遍,以至于 RTL 有一个 wrapper 选项,您可以使用它来提供一个包装器组件,该组件提供组件使用的所有上下文,即路由、主题、 redux、语言环境翻译等...

示例:

const RouterWrapper = ({ children }) => (
  <MemoryRouter>
    {children}
  </MemoryRouter>
);

...

import { RouterWrapper } from '../path/to/RouterWrapper";

describe('testing Mine Page', () => {
  test('check table components', () => {
    render(<MineTable />, { wrapper: RouterWrapper });
    const pageTitle = screen.getByRole('heading', { name: /mina/i });
    expect(pageTitle).toBeInTheDocument();
  });
});

有关详细信息,请参阅 custom render