【问题标题】:Mock exported function in module在模块中模拟导出函数
【发布时间】:2016-08-04 09:52:50
【问题描述】:

我有两个包含导出函数的模块。 “ModuleB”使用“ModuleA”中的功能。现在我想测试“ModuleB”并模拟“ModuleA”中使用的函数。

我将 ES6 与 babel 一起使用。对于测试,我使用 karma 和 jasmine。

我尝试使用 babel-rewire 和 inject-loader,但它不起作用。我对这一切有点陌生,我想我只是做错了什么。因此,感谢您的帮助!

moduleA.js

export function getResult() {
    return realResult;
}

moduleB.js

import * as ModuleA from './moduleA'

export function functionToTest() {
    let result = ModuleA.getResult();
    // do stuff with result which I want to test
}

我的测试

it("does the right thing", () => {
    // I tried using rewire, but this gives me an exception:
    ModuleB.__Rewire__('ModuleA', {

        getResult: () => {
            return fakeResult;
        }
    });

    let xyz = ModuleB.functionToTest(canvas, element);
});

【问题讨论】:

    标签: javascript unit-testing jasmine ecmascript-6


    【解决方案1】:

    看看这个库https://www.npmjs.com/package/mockery 我想这正是你想要的。希望对您有所帮助!

    已编辑:

    基本上你必须在每个测试中使用 mockery 来模拟你的函数,唯一的问题是你必须使用 require 来对抗你想要模拟的模块的 import。看这个例子:

    const moduleUnderTest = './moduleB.js';
    const moduleA_fake = { getResult: () => { return "This is a fake result"; } } ;
    
    describe("Mocking functions", () => {
    
        it('Should be Fake Result', (done) => {
    
            mock.registerAllowable(moduleUnderTest);
            mock.registerMock('./moduleA.js', moduleA_fake);
    
            mock.enable({ useCleanCache: true });
    
            let ModuleB = require(moduleUnderTest);
            let res = ModuleB.functionToTest();
    
            res.should.be.eql("This is a fake result");
    
    
            mock.disable();
            mock.deregisterAll();
    
            done();
        });
    
        it('Should be Real Result', (done) => {
    
            let ModuleB = require(moduleUnderTest);
            let res = ModuleB.functionToTest();
    
            res.should.be.eql("real foo");
    
            done();
        });
    
    });
    

    你可以看到完整的例子Here

    【讨论】:

    • 你能给我一个例子吗?这是如何与 es6 一起工作的?
    • 当然,看看我为你做的这个例子,棘手的事情是库被设计成与 require 一起使用,所以在任何想要模拟函数的测试中,你都必须调用模块要求反对进口。 See Example
    • 非常感谢!现在我明白如何使用它了。但我仍然有一些麻烦:我通过npm install mockery 安装它并通过let mock = require('mockery') 创建mock。运行测试时出现错误ERROR in ./~/mockery/mockery.js Module not found: Error: Cannot resolve module 'module'。知道这是什么吗?
    • 你能给我看一些代码吗?您导入模块的方式似乎有问题。“ ./~/ ”此路径永远不会存在于您的计算机中。
    • 当然。一旦我创建测试并尝试获取模块,就会发生错误。我刚刚写了describe("Mocking functions", () => {let mock = require('mockery'); } 我得到的错误是Error: Cannot find module "module" in C:/<cut this>/tests.webpack.js。也许是我的 webpack 配置有问题?不过,我终于找到了使用babel-rewire 的方法。当然我很好奇嘲讽是如何产生的,但我不想占用你太多时间。如果您知道我为什么会收到此错误,请告诉我。否则,我将使用 babel-rewire。 :)
    【解决方案2】:

    对于任何对它如何与babel-rewire 一起使用感兴趣的人:诀窍是使用__RewireAPI__。

    import * as ModuleB from '../ModuleB'
    import {__RewireAPI__ as ModuleBRewire} from '../ModuleA';
    
    it("does the right thing", () => {
        let moduleAMock = {
            getResult: () => {
                return fakeResult;
            }
        }
    
        ModuleBRewire.__Rewire__('ModuleA', moduleAMock);
    
        let xyz = ModuleB.functionToTest();
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-16
      • 2019-11-07
      • 2017-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-14
      相关资源
      最近更新 更多