【问题标题】:How to mock method of instance of module with Jest?如何用 Jest 模拟模块实例的方法?
【发布时间】:2018-06-21 04:54:18
【问题描述】:

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

这是我的主程序文件 连接.ts

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 运行时,它会抛出错误。我怀疑这是由于错误的模拟。你能帮我开玩笑地正确实现这个模块的模拟吗?

【问题讨论】:

  • 我过去试过这个,但我无法让它工作。我隐约记得这件事。我想如果您使用require 而不是import,它可能会起作用。
  • 我试过了,还是不行。

标签: javascript typescript jestjs


【解决方案1】:

嘲笑本身是正确的,但顺序是错误的。 import 语句是静态的,仅在顶层提升 - 所以 getTokensWithAuthCode 首先使用原始 box-node-sdk 模块导入。然后模拟不会生效,因为加载的模块不会刷新内部加载的依赖项。

解决这个问题的几种方法。

  1. 使用 babel-jest,将 mocking 提升到顶层。然后即使使用 import 语句,您的模拟也会在导入之前被吊起。例如

    import {getTokensWithAuthCode} ...
    jest.mock('box-node-sdk' ...);
    

    将被正确排序到

    jest.mock('box-node-sdk' ...);
    const {getTokensWithAuthCode} = require(...) //transpiled
    

    ts-jest 如果您使用 TypeScript,则会为您执行此操作。

  2. 在模拟您的依赖项后,在每个测试夹具中动态需要 getTokensWithAuthCode

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-09
    • 2018-02-19
    • 2018-08-17
    • 2017-12-09
    • 1970-01-01
    • 1970-01-01
    • 2018-01-26
    • 2019-08-17
    相关资源
    最近更新 更多