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

问题描述 投票:0回答:4

我必须测试一个根据 url 路径参数中的国家/地区和语言进行渲染的组件。所以我想知道组件是否根据参数的变化正确渲染。

我正在模拟 useParams 并设置一些适用于大多数测试的必需值。现在,对于特定情况,我需要更改参数。

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

如何覆盖测试中的语言?

谢谢你

javascript react-hooks jestjs mocking
4个回答
2
投票

您可以使用

useParams
,而不是嘲笑 
<MemoryRouter initialEntries>
,例如:

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();
});

在线演示

Edit eloquent-tu-imqcbh


1
投票

根据 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
});

0
投票

是的 将路由器包含在您的应用程序组件中; 始终在测试中渲染 App 组件(不要像 Locations 这样的子组件); 通过查找并单击页面上的链接导航到测试中的页面 这种方法的优点:您不需要阅读本文的其余部分🙃(并且您的测试设置将不那么复杂)。缺点:您无法在测试设置中立即加载路由历史记录(当前页面和先前页面);您需要经历所有用户交互才能构建历史记录。


0
投票

你可以这样使用它:

const mockUseParams = jest.fn().mockResolvedValue({
    slug: 'basic-details',
    id: '123',
  });

jest.mock('react-router-dom', () => ({
    ...jest.requireActual('react-router-dom'),
    useParams: () => mockUseParams(),
}));
© www.soinside.com 2019 - 2024. All rights reserved.