Issue
When wanting to mock external modules with Jest, we can use the jest.mock()
method to auto-mock functions on a module.
We can then manipulate and interrogate the mocked functions on our mocked module as we wish.
For example, consider the following contrived example for mocking the axios module:
import myModuleThatCallsAxios from '../myModule';
import axios from 'axios';
jest.mock('axios');
it('Calls the GET method as expected', async () => {
const expectedResult: string = 'result';
axios.get.mockReturnValueOnce({ data: expectedResult });
const result = await myModuleThatCallsAxios.makeGetRequest();
expect(axios.get).toHaveBeenCalled();
expect(result).toBe(expectedResult);
});
The above will run fine in Jest but will throw a Typescript error:
Property 'mockReturnValueOnce' does not exist on type '(url: string, config?: AxiosRequestConfig | undefined) => AxiosPromise'.
The typedef for axios.get
rightly doesn't include a mockReturnValueOnce
property. We can force Typescript to treat axios.get
as an Object literal by wrapping it as Object(axios.get)
, but:
What is the idiomatic way to mock functions while maintaining type safety?
Solution
Starting with ts-jest 27.0 mocked
from ts-jest
will be deprecated and removed in 28.0 you can check it in the official documentation. So please use instead mocked
from jest
. Here's the documentation
So for your example:
import myModuleThatCallsAxios from '../myModule';
import axios from 'axios';
jest.mock('axios');
// OPTION - 1
const mockedAxios = jest.mocked(axios, true)
// your original `it` block
it('Calls the GET method as expected', async () => {
const expectedResult: string = 'result';
mockedAxios.mockReturnValueOnce({ data: expectedResult });
const result = await myModuleThatCallsAxios.makeGetRequest();
expect(mockedAxios.get).toHaveBeenCalled();
expect(result).toBe(expectedResult);
});
Answered By - Melchia
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.