APIからのコールバックを使用して関数の1つをモックしようとすると、TypeError: specificMockImpl.apply is not a function
としてエラーが発生します
import { IEnvironmentMap, load } from 'dotenv-extended';
import { getTokensWithAuthCode, sdk } from '../src/connection-manager';
describe('getTokensWithAuthCode function Tests', () => {
jest.useFakeTimers();
let boxConfig: IEnvironmentMap;
beforeAll(() => {
boxConfig = load({
errorOnMissing: true,
});
});
it('should reject a promise if there is wrong auth code provided', async () => {
sdk.getTokensAuthorizationCodeGrant = jest.fn().mockImplementation(boxConfig.BOX_AUTH_CODE, null, cb => {
cb('Error', null);
});
try {
const tokens = await getTokensWithAuthCode();
} catch (error) {
expect(error).toBe('Error');
}
});
});
そして、テストしようとしている私の関数は次のとおりです。
import * as BoxSDK from 'box-node-sdk';
import { IEnvironmentMap, load } from 'dotenv-extended';
import {ITokenInfo} from '../typings/box-node-sdk';
const boxConfig: IEnvironmentMap = load({
errorOnMissing: true,
});
export const sdk: BoxSDK = new BoxSDK({
clientID: boxConfig.BOX_CLIENT_ID,
clientSecret: boxConfig.BOX_CLIENT_SECRET,
});
/**
* - Use the provided AUTH_CODE to get the tokens (access + refresh)
* - Handle saving to local file if no external storage is provided.
*/
export async function getTokensWithAuthCode() {
return new Promise((resolve: (tokenInfo: ITokenInfo) => void, reject: (err: Error) => void) => {
if (boxConfig.BOX_AUTH_CODE === '') {
reject(new Error('No Auth Code provided. Please provide auth code as env variable.'));
}
sdk.getTokensAuthorizationCodeGrant(boxConfig.BOX_AUTH_CODE, null, (err: Error, tokenInfo: ITokenInfo) => {
if (err !== null) {
reject(err);
}
resolve(tokenInfo);
});
});
}
冗談で機能をモックする他の方法はありますか?記事を読みました https://www.zhubert.com/blog/2017/04/12/testing-with-jest/
この行では、関数をmockImplementation
に渡すのではなく、次の3つの引数を渡します。
jest.fn().mockImplementation(boxConfig.BOX_AUTH_CODE, null, cb => {
cb('Error', null);
});
中かっこをいくつか見逃したようです。次のように切り替えてみてください。
jest.fn().mockImplementation((boxConfig.BOX_AUTH_CODE, null, cb) => {
cb('Error', null);
});
他の場所で使用されているconst
を変更しようとしない方がよいでしょう。getTokensWithAuthCode
を変更して、パラメーターとしてsdk
を受け取るようにすることができます。したがって、テストでは、モック関数を引数として渡すため、sdk
を直接変更するよりも予測可能な動作になります。
コードでは、たとえば署名getTokensWithAuthCodeUnbound(sdk)
を使用して2番目のgetTokensWithAuthCode
実装を作成し、それをエクスポートできます。この実装は、テストで使用されます。
同じgetTokensWithAuthCode
名を使用してエクスポートするには、次のように呼び出します。
export const getTokensWithAuthCode = getTokensWithAuthCodeUnbound.bind(null, sdk)
そうすれば、アプリはデフォルトのgetTokensWithAuthCodeUnbound
にバインドされたsdk
を使用し、その実装をより簡単にテストできます。
Mozilla Developer Network(MDN)bind
ドキュメント 。