I'm trying to wrap a jest.mock into a function so I can reuse it in multiple files. My use case is for react hooks, and I am using typescript. Currently my test files looks something like this:
test.tsx
//some imports
jest.mock('../path/to/hoook/whatever', () => ({
useWhatever: jest.fn()
}))
const mockResult = () => {
return ({
some stuff
};
};
describe('Component', () => {
let wrapper;
beforeEach(() => {
mocked(useWhatever).mockClear();
mocked(useWhatever).mockImplementation(() => mockResult);
wrapper = shallow(
<Component />
);
});
//tests below
});
This works just fine, but this whatever hook gets used by other components and I'm trying to wrap up the jest.mock for reuse in other tests. What i'm trying to do looks something like this:
mocks.ts
export const mockWhatever = () => jest.mock('../path/to/hoook/whatever', () => ({
useWhatever: jest.fn()
}))
export const mockResult = () => {
return ({
some stuff
};
};
test.tsx
//some imports
mockWhatever();
describe('Component', () => {
let wrapper;
beforeEach(() => {
mocked(useWhatever).mockClear();
mocked(useWhatever).mockImplementation(() => mockResult);
wrapper = shallow(
<Component />
);
});
//tests below
});
When doing it this way, I get errors like "TypeError: utils_1.mocked(...).mockClear is not a function" when running the test. Is it possible to wrap mocks like this? And if so, what might I be doing wrong or missing?
Thanks
jest.mock
is hoisted above imports with Babel transform, this is the reason why this works as intended:
import ... from 'whatever';
jest.mock('whatever', ...);
It's impossible to achieve the same thing for mockWhatever
without custom Babel transform, therefore modules are imported before they are mocked. import
needs to be replaced with require
and in order for a mock to take effect, import..require
syntax can be used for TypeScript type safety.
__mocks__
is a way to reuse module mocks that Jest provides. Considering that there's __mocks__/whatever.js
mocked module, it's used as a mock with jest.mock('whatever')
.