本文介绍了如何使用Jest模拟 umiJs 的 history.push 的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
一、问题描述
正在尝试在 react + umiJs 的项目上模拟 umiJs 内置的 history.push 并使用 @testing-library/react ,该如何进行测试呢?
根据百度搜索到的使用 jest.mock(moduleName,factory,options),果不其然还是报错了。但不要灰心,往下看有惊喜~
NoFoundPage.tsx
import { Card } from 'antd';
import React from 'react';
import { history } from 'umi';
import styles from '@/components/403/index.less';
const NoFoundPage: React.FC = () => {
return (
<div className={styles.mainContent}>
<Card
bordered={false}
title={null}
className={styles.cardBox}
>
<div className={styles.text}>抱歉,你訪問的頁面不存在</div>
<div className={styles.goback} onClick={() => history.push('/')}>
返回首頁
</div>
</Card>
</div>
);
};
export default NoFoundPage;
尝试使用 jest.mock 方法解决,但是还是有问题。
NoFoundPage.test.tsx
import NoFoundPage from '@/pages/404';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { MemoryRouter } from 'umi';
const mockHistoryPush = jest.fn();
jest.mock('umi', () => ({
...jest.requireActual('umi'),
useHistory: () => ({
push: mockHistoryPush,
}),
}));
test('redirects to correct URL on click', async () => {
render(
<MemoryRouter>
<NoFoundPage />
</MemoryRouter>,
);
await userEvent.click(screen.getByText('返回首頁'));
screen.debug();
expect(mockHistoryPush).toHaveBeenCalledTimes(1);
expect(mockHistoryPush).toHaveBeenCalledWith('/');
});
报错了!错误信息如下图:
报错的原因:是mockHistoryPush方法没有被调用到。
因为项目的使用配置与他们使用的 react-router-dom 的 useHistory不一样,所以使用方法应该要有所改变。根据自己的理解,react-router-dom的 useHistory 是一个方法,需要将 history 初始化之后才能使用 push,而 umiJs 的 history 是直接调用,说明history拥有push方法。
后来看到一篇文章 jest中的mock,jest.fn()、jest.spyOn()、jest.mock()_微个日光日的博客-CSDN博客,改变策略,采用了 jest.spyOn(object,methodName) , 问题解决了。如下仅供参考!
import NoFoundPage from '@/pages/404';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { MemoryRouter, history } from 'umi';
const mockHistoryPush = jest.spyOn(history, 'push');
/** 重定向回正确的url地址 */
test('redirects to correct URL on click', async () => {
render(
<MemoryRouter>
<NoFoundPage />
</MemoryRouter>,
);
await userEvent.click(screen.getByText('返回首頁'));
screen.debug();
expect(mockHistoryPush).toBeCalledTimes(1);
expect(mockHistoryPush).toHaveBeenCalledWith('/');
});