I am using axios.create
method to create and configure axios
instance. And I can't get it to work in tests with vi.fn()
so I cannot assert if endpoint was called.
workaround for tests to be able to return data from api calls looks like
return {
AxiosInstance: {},
AxiosRequestConfig: {},
default: {
post: vi.fn(),
create: vi.fn(() => {
return {
post: (url: string, config: object) => {
return Promise.resolve({ status: 200 });
},
get: (url: string, config: object) => {
return Promise.resolve({ status: 200 });
},
interceptors: {
request: {
use: vi.fn(),
eject: vi.fn(),
},
response: {
use: vi.fn(),
eject: vi.fn(),
},
},
};
}),
},
};
});
But would like to use something like
(axios.get as MockedFunction<typeof axios.get>).mockImplementationOnce(
() => promise
);
maybe someone mocked axios.create
using vitest
and could share configuration?
If, for instance, you're using axios.create()
in your codebase to generate an AxiosInstance
, you can mock this functionality as follows in your Vitest test file:
const mocks = vi.hoisted(() => ({
get: vi.fn(),
post: vi.fn(),
}));
vi.mock('axios', async(importActual) => {
const actual = await importActual<typeof import ('axios')>();
const mockAxios = {
default: {
...actual.default,
create: vi.fn(() => ({
...actual.default.create(),
get: mocks.get,
post: mocks.post,
})),
},
};
return mockAxios;
});
Initially, we set up the mocks
object that includes the get
and post
functions we want to mock. Using vi.hoisted()
, we ensure these mocked functions are hoisted (i.e., moved to the top of the scope), allowing us to reference them within our vi.mock()
function.
Then, we mock the entire axios
module using vi.mock()
. In order to maintain the existing functionality that we don't intend to mock, we employ importActual
to import the real axios
module. We then specify the parts we wish to mock, namely the create
function and the get
/post
functions.
With these mocks in place, we can now spy on our mocked get
and post
methods. Here's an example of how to do it:
it('should call axios.get', async() => {
mocks.get.mockResolvedValueOnce({
data: {},
});
await api.getFromAPI();
expect(mocks.get).toHaveBeenCalled(); // should return true
});
In the test case, we mock a resolved value for our get
method and call the function we want to test (api.getFromAPI()
in this case). We then check whether our mocked get
function has been called using expect().toHaveBeenCalled()
.
This setup provides a controlled environment to test the interactions with the axios library in our code.