【问题标题】:JEST error TypeError: specificMockImpl.apply is not a functionJEST 错误 TypeError: specificMockImpl.apply 不是函数
【发布时间】:2018-06-22 04:56:10
【问题描述】:

尝试使用来自 api 的回调来模拟其中一个函数并得到错误为 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/

【问题讨论】:

    标签: javascript typescript jestjs


    【解决方案1】:

    最好不要尝试改变在别处使用的const。
    您可以更改getTokensWithAuthCode 以使其接收sdk 作为参数,因此在您的测试中,您会将模拟函数作为参数传递,因此比直接更改sdk 具有更可预测的行为。

    在您的代码中,您可以创建第二个getTokensWithAuthCode 实现,例如签名getTokensWithAuthCodeUnbound(sdk),然后将其导出。此实现将在您的测试中使用。
    使用相同的getTokensWithAuthCode 名称导出,您会调用:

    export const getTokensWithAuthCode = getTokensWithAuthCodeUnbound.bind(null, sdk)
    

    这样,您的应用将使用与默认sdk 绑定的getTokensWithAuthCodeUnbound,您可以更轻松地测试其实现。

    Mozilla 开发者网络 (MDN) bind documentation.

    【讨论】:

      【解决方案2】:

      在这一行中,不是将函数传递给mockImplementation,而是传递三个参数:

      jest.fn().mockImplementation(boxConfig.BOX_AUTH_CODE, null, cb => {
        cb('Error', null);
      });
      

      看起来您可能只是错过了一些大括号。尝试将其切换为:

      jest.fn().mockImplementation((boxConfig.BOX_AUTH_CODE, null, cb) => {
        cb('Error', null);
      });
      

      【讨论】:

      • @praveenseela 它在几年前的原始问题的上下文中工作,但如果你试图做类似的事情,那么方法签名可能已经改变或者你正在使用的版本中的某些东西。我建议如果您没有任何运气,最好发布一个新问题,详细说明您看到的错误。
      猜你喜欢
      • 2021-04-19
      • 2019-10-16
      • 2021-05-01
      • 2020-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-10
      • 2021-12-26
      相关资源
      最近更新 更多