如何在jest中覆盖useParams的默认模拟

ssm49v7z  于 2022-12-08  发布在  Jest
关注(0)|答案(3)|浏览(194)

我必须测试一个组件,它根据URL路径参数中的国家和语言呈现。所以我想看看组件是否根据参数的变化正确呈现。
我正在模拟useParams并设置一些适用于大多数测试的必需值。现在,对于一个特定的情况,我需要更改参数。

jest.mock('react-router-dom', () => ({
      ...jest.requireActual('react-router-dom'),
      useParams: () => ({
        language: 'IT'
      })
    }));

如何在测试中覆盖语言?
谢谢你

ddrv8njm

ddrv8njm1#

您可以使用<MemoryRouter initialEntries>来取代useParams,例如:

  • MyComponent.js*
import { useParams } from "react-router-dom";

function MyComponent() {
  const { language } = useParams();
  return (
    <div>
      <h2>My Component page</h2>
      <p>language: {language}</p>
    </div>
  );
}
  • MyComponent.test.js*
import { MemoryRouter } from "react-router-dom";
import { render, screen, fireEvent } from "@testing-library/react";
import "@testing-library/jest-dom";
import App from "./App";

test("Home: Go to `MyComponent: en`", async () => {
  render(
    <MemoryRouter initialEntries={["/"]}>
      <App />
    </MemoryRouter>
  );

  expect(screen.getByText("Home page")).toBeInTheDocument();

  fireEvent.click(screen.getByText("My Component: en"));

  expect(screen.getByText("language: en")).toBeInTheDocument();
  expect(screen.queryByText("language: fr")).not.toBeInTheDocument();
});

test("MyComponent: en", async () => {
  render(
    <MemoryRouter initialEntries={["/myComponent/en"]}>
      <App />
    </MemoryRouter>
  );

  expect(screen.getByText("language: en")).toBeInTheDocument();
});

test("MyComponent: fr", async () => {
  render(
    <MemoryRouter initialEntries={["/myComponent/fr"]}>
      <App />
    </MemoryRouter>
  );

  expect(screen.getByText("language: fr")).toBeInTheDocument();
});

在线演示

8ulbf1ek

8ulbf1ek2#

根据Jest文档上的此页面,尝试以下操作

// create a separate mock function that you can access from tests
// NOTE: the name must start with `mock` and is case sensitive 
const mockUseParams = jest.fn().mockReturnValue({
  language: 'IT',
});

// mock the module using the mock function created above
jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useParams: () => mockUseParams(),
}));

it('should behave differently when the params change', () => {
  mockUseParams.mockReturnValueOnce({
    language: 'EN',
  });

  // test implementation
});
lymgl2op

lymgl2op3#

yes Include the Router in your App component; Always render the App component in your tests (never child components like Locations); Navigate to your pages in tests by finding and clicking links on the page The positives of this approach: you don’t need to read the rest of this post 🙃 (and your test setup will be less complicated). The negatives: you can’t immediately load a routing history (the current page and previous pages) in test setup; you need to go through all the user interactions to build the history.

相关问题