Here's a class I wish to test:
//Request.js
import axios, {AxiosInstance} from 'axios';
import config from './config';
const axiosSingleton: AxiosInstance = axios.create({
baseURL: 'http://localhost:8080',
});
export default class Request {
public async get<$ResponseType = any>(url: string): Promise<void> {
const response = await axiosSingleton.get(url);
return response.data;
}
}
when I try testing this by creating a test file, I am not sure how to mock axios. I tried a bunch of ways including - spyOn and automatic mocking. But they don't seem to work. Here's a version of the test file I am not understanding why it doesn't work
// Request.test.js
import axios from 'axios';
import Request from './Request';
interface ITestResponseDataType {
value: string
}
jest.mock('axios');
describe('Request Tests', () => {
it('should call axios get with the right relativeUrl', async () => {
const getMock = jest.fn();
axios.create.mockReturnValue({
get: getMock
});
getMock.mockResolvedValue({
value: 'value'
});
const data = await new Request().get<ITestResponseDataType>('/testUrl');
expect(getMock.mock.calls.length).toEqual(1);
expect(data).toEqual({
value: 'value'
});
});
});
The error I get when I try running the test is -
TypeScript diagnostics (customize using `[jest-config].globals.ts-jest.diagnostics` option):
src/common/api/Request.test.ts:15:18 - error TS2339: Property 'mockReturnValue' does not exist on type '(config?: AxiosRequestConfig | undefined) => AxiosInstance'.
15 axios.create.mockReturnValue({
This error makes sense, because the type defined in axios for axios.create should not allow .mockReturnValue to be called on .create. So how do I tell typescript that jest has gone in and modified it?
Cast the mock method to jest.Mock
, ie
import axios from "axios" import Request from "./Request"; // Create an Axios mock // Don't worry about the order, Jest will hoist this above the imports // See https://jestjs.io/docs/manual-mocks#using-with-es-module-imports jest.mock("axios", () => ({ create: jest.fn() })) // Customise the `create` mock method (axios.create as jest.Mock).mockReturnValue({ get: getMock })
Just an addition to top rated answer. I would prefer maintaining type definitions when type casting. That can be be rewritten as
(axios as jest.Mocked<typeof axios>).create.mockReturnValue({ get: getMock });
You need to replace the axios.create method with a Jest mock function:
axios.create = jest.fn();
That should allow you to then set its return value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With