簡體   English   中英

開玩笑地嘲笑 react-router-dom useHistory 和其他鈎子

[英]Mocking react-router-dom useHistory and other hooks with jest

我有一個 CRA 和 Typescript (.tsx) 應用程序。 我正在嘗試為需要useHistoryuseRouteMatch的組件編寫測試,但它返回錯誤: TypeError: Cannot read property 'history' of undefined

組件:

const SidebarTreeNav: React.FC<Props> = ( { tree, expanded } ) => {
  const history = useHistory();
  let { url } = useRouteMatch();

  const handleClick = useCallback(
    ( path: string ) => history.push(`${ url }/${ path }`),
    [ history ]);

  return (
    <SidebarTreeNavView expanded={ expanded ?? [ '0' ] }>
      <SidebarTreeNavBlock handleClick={ handleClick } tree={ tree } node={ 0 } />
    </SidebarTreeNavView>
  );
};

export default SidebarTreeNav;

考試:

  beforeEach(() => {
    jest.mock('react-router-dom', () => {
      const originalModule = jest.requireActual('react-router-dom');

      return {
        __esModule: true,
        ...originalModule,
        useRouteMatch: { url: '/entry' },
        useHistory: jest.fn(),
      };
    });

    shallow = createShallow();
    wrapper = shallow(<SidebarTreeNav tree={ [] } />);
  });

  it('<SidebarTreeNav /> should be defined', () => {
    expect(wrapper).toBeDefined();
  });

您可能不再需要此答案,但我會將其發布以供將來參考。

首先,你在錯誤的地方定義了jest.mock ,它必須是靜態的,而不是在每個組件安裝之前useHistory - 這解決了你的useHistory錯誤。 其次,您以錯誤的方式嘲笑useRouteMatch ,它會拋出useRouteMatch不是函數。 第三,你為什么需要__esModule: true

無論如何,這是我的工作解決方案(我刪除了一些不相關的部分):

SidebarTreeNav 組件:

import React, { useCallback } from 'react';
import { useHistory, useRouteMatch } from 'react-router-dom';

const SidebarTreeNav = () => {
  const history = useHistory();
  const { url } = useRouteMatch();

  const handleClick = useCallback(
    (path: string) => history.push(`${url}/${path}`),
    [history]
  );

  // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
  return <div onClick={() => handleClick(url)}>expanded</div>;
};

export default SidebarTreeNav;

測試文件:

import { shallow, ShallowWrapper } from 'enzyme';
import React from 'react';

import SidebarTreeNav from './SideBarTreeNav';

jest.mock('react-router-dom', () => {
  const originalModule = jest.requireActual('react-router-dom');

  return {
    ...originalModule,
    useHistory: jest.fn(),
    useRouteMatch: jest.fn(() => {
      return { url: '/entry' };
    }),
  };
});

describe('whatever', () => {
  let wrapper: ShallowWrapper;

  beforeEach(() => {
    wrapper = shallow(<Temporary />);
  });

  it('<SidebarTreeNav /> should be defined', () => {
    expect(wrapper).toBeDefined();
  });
});

旁注:使用您的示例真的很難,因為您只發布了部分代碼,下次請添加完全復制的 js 小提琴。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM