Javascript 如何用Jest模拟模块实例的方法?

Javascript 如何用Jest模拟模块实例的方法?,javascript,typescript,jestjs,Javascript,Typescript,Jestjs,Test-connection.ts文件为: import { IEnvironmentMap, load } from 'dotenv-extended'; import { getTokensWithAuthCode, sdk } from '../src/connection-manager'; describe('Box API connection tests', () => { jest.useFakeTimers(); let boxConfig: IEn

Test-connection.ts文件为:

import { IEnvironmentMap, load } from 'dotenv-extended';
import { getTokensWithAuthCode, sdk } from '../src/connection-manager';

describe('Box API connection tests', () => {

    jest.useFakeTimers();
    let boxConfig: IEnvironmentMap;

    beforeAll(() => {
        boxConfig = load({
            errorOnMissing: true,
        });
    });

    describe('getTokensWithAuthCode function Tests', () => {

        it('should reject a promise if there is wrong auth code provided', async () => {
            jest.mock('box-node-sdk', () => ({
                 getTokensAuthorizationCodeGrant: jest.fn(),
            }));

            await getTokensWithAuthCode();
            expect(sdk.getTokensAuthorizationCodeGrant).toHaveBeenCalled();
       });
   });
});
这是我的主程序文件 连接

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,
});

export async function getTokensWithAuthCode() {

    return await new Promise((resolve: (tokenInfo: ITokenInfo) => void, reject: (err: Error) => void) => {

        sdk.getTokensAuthorizationCodeGrant(boxConfig.BOX_AUTH_CODE, null, (err: Error, tokenInfo: ITokenInfo) => {
            if (err !== null) {
                reject(err);
            }

            resolve(tokenInfo);
       });
});
}

当以jest--coverage运行时,它抛出了错误。我怀疑这是因为弄错了。您能用jest帮助正确实现此模块的模拟吗?

模拟本身是正确的,但顺序不正确
import
语句是静态的,仅在顶层被提升-因此首先使用原始的
box节点sdk
模块导入
GetTokenWithAuthCode
。然后模拟将不会生效,因为加载的模块不会刷新内部加载的依赖项

有两种方法可以解决这个问题

  • 使用巴别塔笑话,将嘲弄提升到最高水平。然后,即使使用import语句,您的mock也会在导入之前被提升。比如说

    import {getTokensWithAuthCode} ...
    jest.mock('box-node-sdk' ...);
    
    将正确地排序到

    jest.mock('box-node-sdk' ...);
    const {getTokensWithAuthCode} = require(...) //transpiled
    
    ts jest
    如果您使用的是TypeScript,它会为您执行此操作

  • 在模拟依赖项之后,在每个测试夹具中动态地需要
    getTokensWithAuthCode


  • 它们都是关于订购模拟和真正的导入-这里的关键是您应该首先使用工具或手动模拟。

    我过去曾尝试过这一点,但我无法让它工作。我依稀记得那件事。如果您使用
    require
    而不是
    import
    ,我想它可能会起作用。我试过了,它不起作用。