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

Max*_*ôté 16 reactjs jestjs react-router enzyme react-hooks

我正在使用 Enzyme 的浅层方法来测试使用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>;

};
Run Code Online (Sandbox Code Playgroud)

测试:

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

});
Run Code Online (Sandbox Code Playgroud)

谢谢!

Mat*_* H. 36

这适用于我模拟 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();
   });
 });
});

Run Code Online (Sandbox Code Playgroud)

只需声明useParamsjest.fn()外部描述(),然后在每个单元测试中更改其值jest.spyOn

  • 请注意,“Router”是通过此处的默认导入导入的(没有“{}”)。 (4认同)
  • 这是从 @reach/router 迁移到 v6 后唯一对我有用的方法。 (3认同)

小智 8

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

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();
  });
});
Run Code Online (Sandbox Code Playgroud)


Iva*_*van 7

我不知道为什么,在 react-router 库的文档中也找不到它,但是在测试和实现中更改react-router-domreact-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();
  });

});
Run Code Online (Sandbox Code Playgroud)

  • 即使当我从react-router导入这些钩子并模拟react-router包时,它仍然给出相同的错误 Cannot read property 'match' of undefined (13认同)
  • 好吧,我想我找到了:“react-router-dom”没有定义钩子。钩子在“react-router”包中定义。因此,如果你想模拟反应路由器挂钩,你将需要模拟该包。请参阅:https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/modules/index.js (3认同)