React 测试库不适用于 React Router v6

问题描述 投票:0回答:1

我几天前开始学习 React 测试库,但我不知道如何使我的测试与 React Router 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,继续渲染最后一个页面Login。这就像第一次测试渲染的历史仍然存在。有人可以帮助我吗?我想测试我的应用程序的每个页面组件。

reactjs testing react-router
1个回答
4
投票

由于

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();
  });
});

请参阅自定义渲染了解更多详细信息。

© www.soinside.com 2019 - 2024. All rights reserved.