marchaos / jest-mock-extended

Type safe mocking extensions for Jest https://www.npmjs.com/package/jest-mock-extended
MIT License
839 stars 57 forks source link

mockDeep does not work when interface is extended from another type with AxiosInstance #94

Closed lallenfrancisl closed 2 years ago

lallenfrancisl commented 2 years ago
class HttpClient {
    axios: AxiosInstance;

    constructor() {
        this.axios = axios.create({ baseUrl: "http://localhost" })
    }
}

const mockHttpClient: DeepMockProxy<HttpClient> = mockDeep<HttpClient>()

mockHttpClient.axios.post.mockImplementation(() => console.log("test"))

This does not work since the type of this.axios is not mock type. But we can do mockHttpClient.axios.mockImplementation()

My hypothesis is that it does not work since the AxiosInstance is extended from Axios

export interface AxiosInstance extends Axios {
  (config: AxiosRequestConfig): AxiosPromise;
  (url: string, config?: AxiosRequestConfig): AxiosPromise;
}
lallenfrancisl commented 2 years ago

The issue is with the way AxiosInstance interface is defined, in which the interface defines AxiosInstance itself as method. This causes the type of DeepMockProxy to set this.axios type as mock instead of the methods inside this.axios

export declare type DeepMockProxy<T> = {
    [K in keyof T]: T[K] extends (...args: infer A) => infer B ? CalledWithMock<B, A> : DeepMockProxy<T[K]>;
} & T;