jest-mock-axios
jest-mock-axios copied to clipboard
mockAxios.create() may return a new instance of mockAxios
Assuming the following use case:
// api.js
import axios from 'axios';
export function config() {
v1.defaults.baseURL = `${API_BASEURL}/v1`;
v2.defaults.baseURL = `${API_BASEURL}/v2`;
// ...
}
export const v1 = axios.create();
export const v2 = axios.create();
export default v1;
Basic test scenario:
// api.test.js
import mockAxios from 'axios';
import * as Api form './api'
describe('Api', () => {
test('proper configuration', () => {
Api.config();
// the following expectation fails because `mockAxios.create()` returns the singleton
// whose `defaults.baseURL` was overwritten with `${API_BASEURL}/v2` already
expect(Api.v1.defaults.baseURL).toEqual(`${API_BASEURL}/v1`);
expect(Api.v2.defaults.baseURL).toEqual(`${API_BASEURL}/v2`);
})
})
Because mockAxios works with a shared state, a workaround would be to override the create
method and simply return a shalow copy of mockAxios (as in the following example) Since axios.create()
actually appears to be a factory, the mock could also return a new instance. I think this would be ideal. What do you guys think?
//__mocks__/axios.js
import mockAxios from 'jest-mock-axios';
import { cloneDeep } from 'lodash';
mockAxios.create = jest.fn(() => cloneDeep(mockAxios));
export default mockAxios;
Hi,
I agree that there is indeed room for improvement when using multiple axios instances. I'll see how it can be improved over the weekend.
Hi,
so I implemented the desired behavior in the 59-multiple-instances
branch as a proof of concept.
This works, but it adds a significant new problem: If you create separate axios
instances via axios.create()
you can no longer mock them using the mockAxios
default export, because it is two different instances with no shared promise queue. See LowercaseProxy.ts
and the corresponding spec as an minimal example for this. Similar to your example above, the axios
instances need to be exported by the code under test and imported by the test file.
This is somewhat unsatisfactory and I need to think a little bit more about this and how this can be changed to be more backward-compatible (any input welcome!)
I am getting this error ( I am assuming it is tied to this new update)
TypeError: axios.create is not a function
I have a singular instance being created in my file.
sd.instance = axios.create({
baseURL: process.env.SDApiUrl,
httpsAgent: new https.Agent({ keepAlive: true }),
headers: { 'Content-Type': 'application/json' }
})
@rcg-dev I failed to reproduce this error (which isn't that surprising, as create()
is used in the tests for this library as well). Can you do console.log
to find out what axios.create
is, if not a function?
I'm hitting the issue with different instances of axios - is that going to get released? Seems that the fix is in.
@httpete The patch for this is still not merged but only in the branch linked above. As described above I was (and still am) hesitant to merge this in as it would break existing, more simple usages of this library. I'm still unsure how to solve this appropriately. Any input welcome.
my $0.02:
when using instances of axios, they should be passed in. in other words, a class that calls _axiosInstance.post()
should take in the _axiosInstance
as a dependency somehow, e.g. in its constructor.
i would expect the jest-mock-axios
library to give me the ability to instantiate a mocked AxiosInstance
instance that I can then pass into my constructor.
so I implemented the desired behavior in the
59-multiple-instances
branch as a proof of concept.
The link does not appear to work anymore.
In my case I use multiple axios instances each configured with it's own interceptor. This seems to wipe out the axios instance that I create.
In the end I just implemented by own https://stackoverflow.com/a/71961832/242042