Reputation: 42546
I am trying to mock react-router-dom
in one of my test cases so that the useHistory
hook will function in my tests. I decide to use jest.mock
to mock the entire module, and jest.requireActual
to preserve the other properties that I may not want to mock.
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useHistory: () => ({
location: {
pathname: '/list',
},
}),
}));
This is actually derived from one of the highly rated solutions to the following question: How to mock useHistory hook in jest?
However, the TypeScript compiler is flagging the following error on the following line ...jest.requireActual('react-router-dom'),
TS2698: Spread types may only be created from object types.
Interestingly, I only face this issue after updating jest and ts-jest to the latest versions (jest v26). I do not face any of these issues when I was using jest 24.x.x.
"@types/jest": "^26.0.4",
"jest": "^26.1.0",
"ts-jest": "^26.1.1",
Does anyone know how to solve this issue for the latest jest versions?
Upvotes: 27
Views: 12296
Reputation: 21
You can simply do as object
to satisfy the Typescript. It's not ideal as the type is not very specific, but it does its job and is definitely better than as any
:))
jest.mock('react-router-dom', () => ({
...(jest.requireActual('react-router-dom') as object),
useHistory: ...
}));
Upvotes: 1
Reputation: 361
In case anyone comes across this when using it for typescript
instead of react-router-dom
, what worked for me is:
import ts from 'typescript';
jest.mock('typescript', () => ({
...jest.requireActual('typescript') as Record<string, unknown>,
nodeModuleNameResolver: ...,
}));
Upvotes: 0
Reputation: 222548
jest.requireActual
returns unknown
type that cannot be spread.
A correct type is:
import * as ReactRouterDom from 'react-router-dom';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom') as typeof ReactRouterDom,
useHistory: ...,
}));
A quick fix is any
:
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom') as any,
useHistory: ...,
}));
It's acceptable because it doesn't impair type safety in this case.
Since react-router-dom
is ES module, a more correct way to mock it is:
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom') as any,
__esModule: true,
useHistory: ...,
}));
Upvotes: 50