使用React Router和React Testing Library测试后退按钮

5

我有一个组件,它使用React Router v6的useNavigate钩子允许用户在历史记录中向后导航。然而,当我用navigate(-1)调用该函数时,测试似乎会失败,但如果我传递一个字符串URL,例如navigate("/home"),则测试通过。有人知道如何正确测试navigate(-1)吗? 这里是一个CodeSandbox来说明这个问题:https://codesandbox.io/s/navigate-back-test-yt82g3?file=/src/navigateBack.test.tsx

import { renderWithRouter } from "./testUtils";
import { screen } from "@testing-library/react";

it("goes back", () => {
  function Home() {
    let navigate = useNavigate();

    function handleClick() {
      navigate("/about");
    }

    return (
      <div>
        <h1>Home</h1>
        <button onClick={handleClick}>about me</button>
      </div>
    );
  }

  function About() {
    let navigate = useNavigate();

    function handleClick() {
      navigate(-1); // test failed
      // navigate("/home"); // test passed
    }

    return (
      <div>
        <h1>About</h1>
        <button onClick={handleClick}>go back</button>
      </div>
    );
  }

  const { user } = renderWithRouter(
    <Routes>
      <Route path="home" element={<Home />} />
      <Route path="about" element={<About />} />
    </Routes>,
    {
      route: "/home"
    }
  );

  user.click(screen.getByText(/about me/i));

  user.click(screen.getByText(/go back/i));

  expect(window.location.pathname).toBe("/home");
});
1个回答

0

如果您只是想测试后退导航,我建议使用 MemoryRouter 并提供初始路由。您只需要一个路由来返回。我认为 renderWithRouter 渲染器存在一些小问题,所以直接用 MemoryRouter 包装组件即可。

示例:

import { render } from "@testing-library/react";
import user from "@testing-library/user-event";
import {
  MemoryRouter as Router,
  Route,
  Routes,
  useNavigate
} from "react-router-dom";
import { screen } from "@testing-library/react";

function Home() {
  const navigate = useNavigate();

  function handleClick() {
    navigate("/about");
  }

  return (
    <div>
      <h1>Home</h1>
      <button onClick={handleClick}>about me</button>
    </div>
  );
}

function About() {
  const navigate = useNavigate();

  function handleClick() {
    navigate(-1);
  }

  return (
    <div>
      <h1>About</h1>
      <button onClick={handleClick}>go back</button>
    </div>
  );
}

it("goes back", () => {
  render(
    <Router initialEntries={["/about"]}>
      <Routes>
        <Route path="home" element={<Home />} />
        <Route path="about" element={<About />} />
      </Routes>
    </Router>
  );

  user.click(screen.getByText(/go back/i));

  expect(window.location.pathname).toBe("/");
});

Edit testing-back-button-using-react-router-and-react-testing-library


嗨,Drew,这会产生一个误报,因为对于react-router 6来说,Router的位置并不与任何外部来源绑定。 参考:https://reactrouter.com/en/main/router-components/memory-router#memoryrouter - undefined
@IsabeauBergeron 这就是在使用MemoryRouter进行节点环境的单元测试的关键所在,它并不与任何外部内容耦合,但是是的,在codesandbox中,这个单元测试似乎是有问题的。 - undefined

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