MemoryRouter 和 Router 关于使用 react-testing-library 进行测试的区别

Difference between MemoryRouter and Router concerning testing with react-testing-library

我在一个小应用程序上工作,以使用 jest 和 React-Testing-Library 熟悉 React 中的测试等。

在我的 <App /> 组件中,我有一个 Routes 和两个 Route。其中一个看起来像这样:

<Route path='/' element={<RequireAuth><Dashboard /></RequireAuth>} />

如果用户未登录,<RequireAuth /> 通过 <Navigate to="/login" />.

将用户重定向到 Login /> 组件

这仅供参考。所有这些都有效。但是很长一段时间,我无法通过测试来检查导航是否发生。我想,我的问题是我在 React-Testing-Librariesrender() 方法中使用的 Route 方法。如果我使用 <MemoryRouter /> 测试通过,但如果我将 <App /> 包装在 <Router location={history.location} navigator={history} />..

中则测试不通过

在接下来的stackblitz中,我实现了两个版本。那个不起作用的,目前被注释掉了。有人能告诉我,为什么它只适用于 MemoryRouter?您可以在 src/routing.test.tsx 中找到测试。您可以 运行 使用 npm 运行 test 进行测试。 https://stackblitz.com/edit/github-nfj4lw?file=src/routes.test.tsx

Routeris not environment specific 的低级函数。正如文档所述,您可能永远不想用它来渲染您的组件。 用更高级别的环境感知函数替换它,例如 BrowserRouter 或 (MemoryRouter) 使您的测试通过:

// routes.test.tsx
import { BrowserRouter } from 'react-router-dom';
it('Testing if Route Login gets rendered by default', () => {
  render(
    
    <BrowserRouter>
      <Provider store={store}>
        <App />
      </Provider>
    </BrowserRouter>
  );

  expect(
    screen.getByText('Welcome to nutri. Please Login.')
  ).toBeInTheDocument();
});

如果您想要更多,可以通过查询 location/history 堆栈来添加更多断言。

注意:使用MemoryRouter in tests is preferred to BrowserRouter since it allows you to keep your routing history independent of any external source. React-router uses it in many of its tests.