javascript - 如何使用 Jest 模拟同一模块中的函数?

标签 javascript testing mocking jestjs

正确模拟以下示例的最佳方法是什么?

问题是在导入时间之后,foo 保留对原始未模拟的 bar 的引用。

module.js:

export function bar () {
    return 'bar';
}

export function foo () {
    return `I am foo. bar is ${bar()}`;
}

module.test.js:

import * as module from '../src/module';

describe('module', () => {
    let barSpy;

    beforeEach(() => {
        barSpy = jest.spyOn(
            module,
            'bar'
        ).mockImplementation(jest.fn());
    });


    afterEach(() => {
        barSpy.mockRestore();
    });

    it('foo', () => {
        console.log(jest.isMockFunction(module.bar)); // outputs true

        module.bar.mockReturnValue('fake bar');

        console.log(module.bar()); // outputs 'fake bar';

        expect(module.foo()).toEqual('I am foo. bar is fake bar');
        /**
         * does not work! we get the following:
         *
         *  Expected value to equal:
         *    "I am foo. bar is fake bar"
         *  Received:
         *    "I am foo. bar is bar"
         */
    });
});

我可以改变:

export function foo () {
    return `I am foo. bar is ${bar()}`;
}

到:

export function foo () {
    return `I am foo. bar is ${exports.bar()}`;
}

但我认为在任何地方都这样做是非常丑陋的。

最佳答案

另一种解决方案是将模块导入到它自己的代码文件中,并使用所有导出实体的导入实例。像这样:

import * as thisModule from './module';

export function bar () {
    return 'bar';
}

export function foo () {
    return `I am foo. bar is ${thisModule.bar()}`;
}

现在模拟 bar 真的很容易,因为 foo 也使用了 bar 的导出实例:

import * as module from '../src/module';

describe('module', () => {
    it('foo', () => {
        spyOn(module, 'bar').and.returnValue('fake bar');
        expect(module.foo()).toEqual('I am foo. bar is fake bar');
    });
});

将模块导入自己的代码看起来很奇怪,但由于 ES6 对循环导入的支持,它工作起来非常顺利。

关于javascript - 如何使用 Jest 模拟同一模块中的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45111198/

相关文章:

unit-testing - RPA 中的自动化测试

javascript - PhoneGap 中的 postMessage 不起作用 - iframe 到父消息传递

javascript - ExtJS - 如何使用代理、模型?它们有什么关系?

javascript - Google 地点使用视口(viewport)而不是半径

unit-testing - 任何支持多种 RPC 协议(protocol)来测试不同组件的测试工具或框架

html - 你用什么来测试你网站上的手持css?

android - 在 TestCase 中启动第二个 Activity (这不是被测 Activity )

scala - 我可以在 Specs2 测试中使用模拟文件写入文件吗?如果是这样,怎么办?

javascript - 更改 DOM 元素的代码行

python - Pytest 的 Mock/Monkeypatch BeautifulSoup html 对象