I will also add here my 2 cents. Since I had similar problems. In my organization we are using vite, but it should work with jest as well. I am pretty sure about it, since I made the migration from jest to vite a year ago.
First i dont like the __mocks__
solution mentioned above, it would be nice if you had a custom AxiosConfig.ts class that looks like this
import axios, { AxiosInstance } from 'axios'
class AxiosConfig {
unsecuredAxios: AxiosInstance
securedAxios: AxiosInstance
constructor() {
this.securedAxios = this.createSecuredAxios()
this.unsecuredAxios = axios.create()
}
private createSecuredAxios(): AxiosInstance {
return instance
}
const axiosConfig = new AxiosConfig()
export const securedAxios: AxiosInstance = axiosConfig.securedAxios
export const unsecuredAxios: AxiosInstance = axiosConfig.unsecuredAxios
Then you have most likely a folder that holds your AxiosConfig.ts
and in there you could create mocks folder that holds the mocked implementation.
However, I have seen many times things changing and developers (including me) forgetting to change the mocked class. You also have to import it when you want to use it, which can be a lot if 100 tests use your mocked Axios instance. My point is it gets messy.
The way we got around it is like this
In vite.config.ts
test: {
globals: true,
environment: 'jsdom',
passWithNoTests: true,
setupFiles: './src/test/setup.ts'}
And then in the setup.ts
// Set up global mocks
vi.mock('@/yourpath/AxiosConfig', () => {
const mockAxiosImplementation = {
request: vi.fn().mockImplementation(() => {
return Promise.resolve({
status: 200,
statusText: 'OK',
headers: {},
data: [],
config: {}
})
}),
interceptors: {
request: {
use: vi.fn(),
eject: vi.fn()
}
}
}
return {
AxiosConfig: vi.fn().mockImplementation(() => ({
securedAxios: mockAxiosImplementation,
unsecuredAxios: mockAxiosImplementation
})),
securedAxios: mockAxiosImplementation,
unsecuredAxios: mockAxiosImplementation
}
})
Note that this was the best way for us since we use openApi and our automatically created requests look like this.
export class SharedProcedureParametersApi extends BaseAPI implements SharedProcedureParametersApiInterface {
public getRejectionReasons(options?: AxiosRequestConfig) {
return SharedProcedureParametersApiBase(this.configuration).getRejectionReasons(options).then((request) => request(this.axios, this.basePath));
}
No need to wrap anything, just mock it once, and it works fine, I think the CI/CD pipelines for the unit tests in fronted are a bit faster that way.
About this approach
Pros:
-Consistency: Mocks are applied consistently across all tests.
-Convenience: No need to repeat mock definitions for each test.
Cons:
-Global Impact: Accidental side effects in mocks can affect all tests.
-Less Control
In the spirit of the answer above, I hope someone finds this helpful. Cheers.