MemoryRouter 和 Router 在使用 React-testing-library 进行测试方面的区别

Moh*_*emi 7 react-router-dom react-testing-library ts-jest

我使用 jest 和 React-Testing-Library 开发一个小型应用程序,以熟悉 React 中的测试等。

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

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

如果用户未登录,则通过<RequireAuth />重定向用户到组件。 Login /><Navigate to="/login" />

这仅用于上下文。所有这些都有效。但在相当长的一段时间里,我无法通过测试来检查导航是否发生。我想,我的问题是我在 React-Testing-Libraries 方法中使用的 Route 方法render()。如果我使用测试会通过<MemoryRouter />,但如果我包装<App /><Router location={history.location} navigator={history} />..

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

exa*_*cae 6

Router是一个低级函数,不特定于环境。正如文档所述,您可能永远不想用它来渲染您的组件。将其替换为更高级别的环境感知函数,例如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();
});
Run Code Online (Sandbox Code Playgroud)

如果您想要更多内容,可以通过查询位置/历史堆栈来添加更多断言。

注意:在测试中使用MemoryRouter是首选,BrowserRouter因为它允许您保持路由历史记录独立于任何外部源。React-router在许多测试中都使用它。