在jest中适当地嘲笑useParams钩子

juud5qan  于 9个月前  发布在  Jest
关注(0)|答案(1)|浏览(132)

我试图在jest中模拟useParams钩子,并试图使其动态化,这样我就可以模拟它几次。然而,如果我硬编码值,我只能模拟它。以下是我到目前为止得到的:

const mockedUsedNavigate = jest.fn();

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'), // use actual for all non-hook parts
  useNavigate: () => mockedUsedNavigate,
  useParams: () => ({
    hash: '123',
  }),
}));

字符串
这是可行的,因为我硬编码useParam返回一个{ hash: '123' }对象。然而,如果我试图模拟它,它将不起作用:

const mockedUsedNavigate = jest.fn();

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'), // use actual for all non-hook parts
  useNavigate: () => mockedUsedNavigate,
  useParams: () => jest.fn().mockReturnValue({ hash: '123' })
}));


如果我这样做,我的组件将收到一个空值,并且该值不会以我想要的方式被模仿:

const { hash = '' } = useParams<{ hash: string }>();
  console.log('hash: ', hash); ---> ''


所以我不知道我做错了什么...有人能给我指个方向吗?

3lxsmp7m

3lxsmp7m1#

useParams通常返回基于当前路由的路由参数。因此,它不是一个可以使用jest.fn()模仿的函数。useParams钩子返回来自<Route path>匹配的当前URL的动态参数的键/值对的对象。参见此处-> React Router docs
当你使用jest.fn().mockReturnValue({ hash: '123' })时,它返回一个函数,而不是一个对象。因此,调用useParams<{ hash: string }>()将导致一个空对象({})
要使用特定值模拟useParams,您可以直接返回具有所需属性的对象。修改以下代码:

const mockedUseNavigate = jest.fn();

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'), // use actual for all non-hook parts
  useNavigate: () => mockedUseNavigate,
  useParams: () => ({ hash: '123' }),
}));

字符串
这样,当组件调用useParams<{ hash: string }>()时,它将接收对象{ hash: '123' }。不需要额外的jest.fn()mockReturnValue
要在Jest中使用动态值模拟useParams,可以使用以下方法之一:

import { render, screen } from '@testing-library/react';
import { BrowserRouter, MemoryRouter, Route, useParams } from 'react-router-dom';

// Mock the useParams hook
jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useParams: jest.fn(),
}));

describe('YourComponent', () => {
  test('renders with dynamic useParams', () => {
    // Set the desired dynamic value for testing
    useParams.mockReturnValue({ hash: '123' });

    render(
      <MemoryRouter initialEntries={['/your-route/123']}>
        <YourComponent />
      </MemoryRouter>
    );

    // Your testing logic here

    // Ensure that the component received the dynamic value
    const hashValue = screen.getByText(/hash/i).textContent;
    expect(hashValue).toBe('123');
  });
});


import { render } from '@testing-library/react';
import { BrowserRouter as Router } from 'react-router-dom';
import YourComponent from './YourComponent'; // Import your component

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

describe('YourComponent', () => {
  test('should render with dynamic useParams', () => {
    // Mock the dynamic useParams value
    jest.spyOn(require('react-router-dom'), 'useParams').mockReturnValue({ hash: '123' });

    // Render your component within a Router
    render(
      <Router>
        <YourComponent />
      </Router>
    );
  });
});


这里useParams声明在describe()之外,它的值在每个使用jest.spyOn的单元测试中变化。

let dynamicHash = '123'; // Set your initial value

const mockedUseNavigate = jest.fn();

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useNavigate: () => mockedUseNavigate,
  useParams: () => ({ hash: dynamicHash }),
}));

相关问题