jestjs - Hur man på rätt sätt mockar en överbelastad Typescript-funktion med Jest
Jag försöker mocka en enskild funktion på en instans med Typescript och Jest. Instansen är en OAuth2Client från Googles Auth Library. Här är min modul som testas:
sample.ts
import {OAuth2Client } from "google-auth-library";
export async function accessToken(): Promise<string | undefined> {
const client: OAuth2Client = new OAuth2Client(
"clientId", "clientSecret", "https://redirect.com"
);
const response = await client.getToken("code");
return response?.tokens.access_token;
}
För testet skulle jag vilja returnera ett fast svar från getToken-anropet. Det som gör detta lite mer komplicerat är att getToken är överlagrat och att google-auth-library är TypeScript.
getToken(code: string): Promise<GetTokenResponse>;
getToken(options: GetTokenOptions): Promise<GetTokenResponse>;
getToken(code: string, callback: GetTokenCallback): void;
getToken(options: GetTokenOptions, callback: GetTokenCallback): void;
Det här är mitt test:
sample.test.ts
import { OAuth2Client } from 'google-auth-library';
import {accessToken} from "./sample";
import {GetTokenResponse} from "google-auth-library/build/src/auth/oauth2client";
type GetTokenByCode = (code: string) => Promise<GetTokenResponse>
const oAuth2Client = jest.spyOn(OAuth2Client.prototype, 'getToken') as unknown as jest.MockedFunction<GetTokenByCode>;
oAuth2Client.mockImplementation((code: string) => {
if (code != "code") return Promise.reject("Unexpected code.");
const response = {
tokens: {
refresh_token: `abc${code}`,
access_token: "def"
},
res: null
}
return Promise.resolve(response);
});
describe('Sample', function () {
beforeEach(() => {
jest.resetModules();
jest.restoreAllMocks();
});
it('can get a token', async () => {
const token = await accessToken();
expect(token).toBeDefined();
expect(oAuth2Client).toHaveBeenCalled();
});
});
När jag kör detta test får jag följande fel - vilket tyder på att klienten försöker det verkliga anropet.
Error: invalid_client
at Gaxios._request (/Users/foo/dev/token-service/node_modules/gaxios/src/gaxios.ts:158:15)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at OAuth2Client.getTokenAsync (/Users/foo/dev/token-service/node_modules/google-auth-library/build/src/auth/oauth2client.js:124:21)
at Object.accessToken (/Users/foo/dev/token-service/src/functions/sample.ts:7:22)
at Object.<anonymous> (/Users/foo/dev/token-service/src/functions/sample.test.ts:29:23)
Om man tittar på filen .. google-auth-library/build/src/auth/oauth2client.js verkar det som att TS-transpilern genererade en js-funktion med signaturen getToken(codeOrOptions, callback) - som sedan kallar getTokenAsync.
Jag är lite vilse här, mockar jag fel överlagring med jest.spy?