我试图在我的一个测试用例中模拟
react-router-dom
,以便 useHistory
钩子在我的测试中起作用。我决定使用 jest.mock
来模拟整个模块,并使用 jest.requireActual
来保留我可能不想模拟的其他属性。
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useHistory: () => ({
location: {
pathname: '/list',
},
}),
}));
这实际上源自以下问题的高度评价的解决方案之一:How to mock useHistory hook in jest?
但是,TypeScript 编译器在下一行标记以下错误
...jest.requireActual('react-router-dom'),
TS2698:扩展类型只能从对象类型创建。
有趣的是,我只是在将 jest 和 ts-jest 更新到最新版本(jest v26)后才遇到这个问题。当我使用 jest 24.x.x. 时,我没有遇到任何这些问题。
"@types/jest": "^26.0.4",
"jest": "^26.1.0",
"ts-jest": "^26.1.1",
有谁知道最新的 jest 版本如何解决这个问题吗?
jest.requireActual
返回无法传播的 unknown
类型。
正确的类型是:
import * as ReactRouterDom from 'react-router-dom';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom') as typeof ReactRouterDom,
useHistory: ...,
}));
快速解决方法是
any
:
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom') as any,
useHistory: ...,
}));
这是可以接受的,因为在这种情况下它不会损害类型安全。
由于
react-router-dom
是ES模块,更正确的mock方法是:
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom') as any,
__esModule: true,
useHistory: ...,
}));
万一有人在使用它而不是
typescript
时遇到这个问题,对我有用的是:react-router-dom
import ts from 'typescript';
jest.mock('typescript', () => ({
...jest.requireActual('typescript') as Record<string, unknown>,
nodeModuleNameResolver: ...,
}));
即可满足 Typescript。它并不理想,因为类型不是很具体,但它完成了它的工作,并且绝对比
as object
:))更好
as any