使用jest模拟react-router-dom钩子不起作用

rsl1atfo  于 9个月前  发布在  Jest
关注(0)|答案(9)|浏览(144)

我正在使用Enzyme的shallow方法来测试一个组件,该组件使用useParams钩子从URL参数中获取ID。
我试图模拟useParams钩子,这样它就不会调用实际的方法,但它不工作。我仍然得到TypeError: Cannot read property 'match' of undefined,所以它调用实际的useParams,而不是我的模拟。
我的组件:

import React from 'react';
import { useParams } from 'react-router-dom';

export default () => {

  const { id } = useParams();

  return <div>{id}</div>;

};

字符串
测试:

import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import React from 'react';
import Header from './header';
import { shallow } from 'enzyme';

Enzyme.configure({ adapter: new Adapter() });

describe('<Header />', () => {

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

  it('renders', () => {
    const wrapper = shallow(<Header />);
    expect(wrapper).toBeTruthy();
  });

});


谢谢你,谢谢

6ojccjat

6ojccjat1#

这对我来说很有用,可以模拟useParams并在同一个文件中更改每个单元测试的值:

import React from "react";
import { render } from "@testing-library/react";
import Router from "react-router-dom";
import Component from "./Component";

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

const createWrapper = () => {
 return render(<Cases />);
};

describe("Component Page", () => {
 describe("Rendering", () => {
   it("should render cases container", () => {
     jest.spyOn(Router, 'useParams').mockReturnValue({ id: '1234' })
     const wrapper = createWrapper();
     expect(wrapper).toMatchSnapshot();
   });

   it("should render details container", () => {
     jest.spyOn(Router, 'useParams').mockReturnValue({ id: '5678' })
     const wrapper = createWrapper();
     expect(wrapper).toMatchSnapshot();
   });
 });
});

字符串
只需在describe()之外将useParams声明为jest.fn(),然后在每个单元测试中使用jest.spyOn更改其值

erhoui1w

erhoui1w2#

我不知道为什么,在react-router库的文档中也找不到它,但在测试和实现中将react-router-dom更改为react-router对我来说都是有效的。
所以它变成了这样:

import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import React from 'react';
import Header from './header';
import { shallow } from 'enzyme';

Enzyme.configure({ adapter: new Adapter() });

describe('<Header />', () => {

  jest.mock('react-router', () => ({
    useParams: jest.fn().mockReturnValue({ id: '123' }),
  }));

  it('renders', () => {
    const wrapper = shallow(<Header />);
    expect(wrapper).toBeTruthy();
  });

});

字符串

d6kp6zgx

d6kp6zgx3#

我遇到过类似的问题,我是这样解决的:

import { Route, Router } from "react-router-dom";
import { createMemoryHistory } from "history";

const renderWithRouter = (component) => {
  const history = createMemoryHistory({
    initialEntries: ["/part1/idValue1/part2/idValue2/part3"],
  });
  const Wrapper = ({ children }) => (
    <Router history={history}>
      <Route path="/part1/:id1/part2/:id2/part3">{children}</Route>
    </Router>
  );
  return {
    ...render(component, { wrapper: Wrapper }),
    history,
  };
};

describe("test", () => {
  it("test desc", async () => {
    const { getByText } = renderWithRouter(<MyComponent/>);
    expect(getByText("idValue1")).toBeTruthy();
  });
});

字符串

xuo3flqw

xuo3flqw4#

我尝试了这个模拟,但它对我不起作用。错误:无法读取属性'match'的undefined。似乎组件不在路由器内,所以它不能用参数模拟匹配。它对我有效:

import { MemoryRouter, Route } from 'react-router-dom';

const RenderWithRouter = ({ children }) => (
  <MemoryRouter initialEntries={['uri/Ineed']}>
    <Route path="route/Ineed/:paramId">{children}</Route>
  </MemoryRouter>
);
const tf = new TestFramework();
describe('<MyComponent />', () => {
  tf.init({ title: 'Some test' }, props =>
    shallow(
      <RenderWithRouter>
        <MyComponent {...props} />
      </RenderWithRouter>
    )
  );

  it('Some description', () => {
    const wrapper = tf.render().html();
    expect(wrapper).toContain('something');
  });
});

字符串

im9ewurl

im9ewurl5#

您可能会错过按原样添加react-router-dom的其他键。

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

字符串

7kjnsjlb

7kjnsjlb6#

对于我的mocking react-router-dom修复问题:

jest.mock('react-router-dom', () => ({
    useParams: jest.fn().mockReturnValue({ nifUuid: 'nif123' }),
    useHistory: jest.fn()
}));

字符串

syqv5f0l

syqv5f0l7#

我也遇到了同样的问题。我这样嘲笑useParams:

jest.mock('react-router-dom', () => {
  return {
    useParams: () => ({
      id: '123'
    })
  }
})

字符串

uz75evzq

uz75evzq8#

我也有同样的问题。我嘲笑useParams像这样之前描述

const mockedNavigate = jest.fn();

jest.mock("react-router-dom", () => ({
  ...(jest.requireActual("react-router-dom") as any),
  useNavigate: () => mockedNavigate,
  useParams: () => ({
    id: 223250 
  })
}));

字符串

hm2xizp9

hm2xizp99#

我也遇到了同样的问题。从“@testing-library/react”调用“cleanup”函数可以帮助我:

import { cleanup } from '@testing-library/react';

afterEach(() => {
    cleanup();
});

字符串

相关问题