我为此研究了很长时间,没有一个答案能解决问题。我有resetAllMocks
afterEach
测试集。我想模拟一个模块的特定方法。
如果我:
import * as ReactRouter from 'react-router';
const mockPush = jest.fn();
jest.mock('react-router', () => ({
...jest.requireActual('react-router'),
useHistory: () => {
return { push: mockPush };
},
useRouteMatch: jest.fn().mockReturnValue({ url: '' })
}));
它在第一个测试用例中工作得很好,但在第二个测试用例中抛出:TypeError: Cannot destructure property 'url' of 'react_router_1.useRouteMatch(...)' as it is undefined.
如果我:
import * as ReactRouter from 'react-router';
const mockPush = jest.fn();
beforeEach(() => {
jest.mock('react-router', () => ({
...jest.requireActual('react-router'),
useHistory: () => {
return { push: mockPush };
},
useRouteMatch: jest.fn().mockReturnValue({ url: '' })
}));
})
它不做任何事情(不模拟值)。
如果我:
import * as ReactRouter from 'react-router';
jest.mock('react-router');
const mockPush = jest.fn();
beforeEach(() => {
jest.spyOn(ReactRouter, 'useHistory').mockReturnValue({ push: mockPush } as any)
jest.spyOn(ReactRouter, 'useRouteMatch').mockReturnValue({ url: '' } as any)
})
它只是不做任何事情(破坏其他功能而不抛出任何错误)。
如果我:
import * as ReactRouter from 'react-router';
const mockPush = jest.fn();
beforeEach(() => {
jest.spyOn(ReactRouter, 'useHistory').mockReturnValue({ push: mockPush } as any)
jest.spyOn(ReactRouter, 'useRouteMatch').mockReturnValue({ url: '' } as any)
})
抛出:TypeError: Cannot redefine property: useHistory at Function.defineProperty (<anonymous>)
.
不确定在测试后重置所有mock是否如此罕见,因此不需要remock,但我找不到在每次测试前remock的合适解决方案。
最后,我设法通过首先只使用模拟目标方法来解决问题。jest.fn()
,并导入jest.requireActual
。
然后在beforeEach
中执行模拟实现,如:
import * as ReactRouter from 'react-router';
jest.mock('react-router', () => ({
...jest.requireActual('react-router'),
useHistory: jest.fn(),
useRouteMatch: jest.fn()
}));
const mockPush = jest.fn();
beforeEach(() => {
jest.spyOn(ReactRouter, 'useHistory').mockReturnValue({ push: mockPush } as any);
jest.spyOn(ReactRouter, 'useRouteMatch').mockReturnValue({ url: '' } as any);
});