React测试库和Jest中的模拟路由器

7
我正在使用React测试库和Jest编写单元测试,希望检查我的React组件是否成功地能够导航到下一页。
import { fireEvent, render, screen } from "@testing-library/react";
import React from 'react';
import { Provider } from 'react-redux';
import '@testing-library/jest-dom';
import appStore from '../../src/app/redux/store';
import { MemoryRouter, Route } from 'react-router-dom';
import { createMemoryHistory } from 'history';
import { Router } from 'react-router';

const setup = (initialEntries = []) => {
      let inMemHistory = createMemoryHistory({ initialEntries });
      const utils = render(
        <Router history={inMemHistory}>
          <Provider store={appStore}>
            <Component-1 />
          
          </Provider>
        </Router>
      );
 
      const saveButtonElem = screen.getByRole('button', { name: "Save and Continue" });
      return {
            saveButtonElem,
            inMemHistory,
            ...utils,
      }
};

测试:

test('should be able to navigate', async () => {
            const {
                 saveButtonElem,
                  inMemHistory,
                  getByText,
                  queryByText,
                  queryAllByText,
            } = setup(["/component_add"]);

        // Content of Test

            // Saving Config
            fireEvent.click(saveButtonElem);
            console.info("Current Path", inMemHistory.location.pathname);
// Got /component_add on console
// Expected /component_data  after clicking on save button
   
      })

我尝试在点击保存按钮后等待5秒钟,然后再尝试打印路径,但结果仍然相同。


1
你是否正在使用React Router(请参见https://stackoverflow.com/q/65270992/3001761)或类似的工具?你的组件是如何导航的?请提供一个最小可复现示例。 - jonrsharpe
通常那些试图提供帮助的人需要更明确的细节。我根据自己对你问题的理解进行了回答,希望能有所帮助。 - Karthik R
我已经编辑了问题并添加了更多细节,如果您需要更多细节,我已经实现了@KarthikR建议的Option-2。 - Booster
1个回答

8
假设你使用react-router,可以在测试中使用Memory路由器,这样更容易且性能更好。由于我没有IDE的支持,可能会有错别字或语法错误,但应该可以帮助你理解我的建议。
it("should route to the expected page", () => {
  let mockHistory, mockLocation;
  render(
    <MemoryRouter initialEntries={["/currentUri"]}>
      <Component1 />
      // Dummy route that routes for all urls
      <Route
        path="*"
        render={({ history, location }) => {
          mockHistory= history;
          mockLocation= location;
          return null;
        }}
      />
    </MemoryRouter>
  );
  // navigate here on event
  userEvent.click(screen.getByRole('button', {name: /Save/}));
  expect(mockLocation.pathname).toBe("/expectedUri");
});

选项二:
import { createMemoryHistory } from 'history';
import { Router } from 'react-router';

const renderWithHistory = (initialEntries= [], Component) => {
  let inMemHistory = createMemoryHistory({
    initialEntries
  });
  return { 
      ...render(
        <Router history={inMemHistory}>
          <Component />
        </Router >
      ), history };
};

it("should route to the expected page", () => {
      const { history } = renderWithHistory(['/currentUri'], Component1);
      // navigate here on event
      userEvent.click(screen.getByRole('button', {name: /Save/}));
      expect(history.location.pathname).toBe("/expectedUri");
});

它将如何知道需要导航到哪里,它是否足够智能? - Booster
我不明白你的意思。你的代码会在点击保存时执行吗?你的测试用例只是为了验证更新后的URL。 - Karthik R
在保存按钮点击时,我得到的路径与我传递的初始条目相同。 - Booster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接