[英]Mocking react-router-dom hooks using jest is not working
[英]Mocking react-router-dom useHistory and other hooks with jest
我有一個 CRA 和 Typescript (.tsx) 應用程序。 我正在嘗試為需要useHistory
和useRouteMatch
的組件編寫測試,但它返回錯誤: 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.