Jest 测试 React Router Prompt

Jest test React Router Prompt

我有一个包含 React Router <prompt> 的组件,现在我想开玩笑地测试当用户离开该组件并且满足所需的先决条件时是否显示它。我如何模拟这种导航并查看 'Prompt' 是否在 Jest 中被触发?

我不确定 Jest 是否是测试这个的正确工具。你通常会用它来进行单元测试,并测试预期的工作是否应该在你的单元测试范围之外。您想做的事情听起来更像是集成测试。

也许有人需要针对这种情况的解决方案:

import React from "react";
import { render } from "@testing-library/react";
import { Prompt, Route, Router, Switch, useHistory } from "react-router-dom";
import { PromptProps } from "react-router";
import { createMemoryHistory } from "history";

const promptResult = jest.fn(); // jest function which holds "when" value of prompt

jest.mock("react-router-dom", () => {
  const PromptMock: React.FC<PromptProps> = (props: PromptProps) => {
    const history = useHistory();
    if (props.when) {
      history.block(); //simulation of prompt behavior
    }
    promptResult.mockReturnValue(props.when);
    return <div />;
  };

  const originalModule = jest.requireActual("react-router-dom");
  return {
    __esModule: true,
    ...originalModule,
    Prompt: PromptMock,
  };
});

test("Shows prompt on navigation away", () => {
  const history = createMemoryHistory({ initialEntries: ["/path1"] });

  render(
    <Router history={history}>
      <Switch>
        <Route path="/path1">
          <div>
            <Prompt when={true} message={"You have unsaved changes."} />
            <div>Should prevent user from navigation</div>
          </div>
        </Route>
        <Route path="/path2">
          <div>Some other page</div>
        </Route>
      </Switch>
    </Router>
  );

  history.push("path2");

  expect(promptResult()).toBeTruthy();
});

test("Doesn't show prompt on navigation away", () => {
  const history = createMemoryHistory({ initialEntries: ["/path2"] });

  render(
    <Router history={history}>
      <Switch>
        <Route path="/path1">
          <div>
            <Prompt when={true} message={"You have unsaved changes."} />
            <div>Should prevent user from navigation</div>
          </div>
        </Route>
        <Route path="/path2">
          <div>Some other page</div>
        </Route>
      </Switch>
    </Router>
  );

  history.push("path2");

  expect(promptResult()).toBeFalsy();
});