使用 Jasmine spyOn 模拟 Browserify 模块中的函数

Using Jasmine spyOn to mock function in Browserify module

我正在尝试 运行 对函数 (testFunc) 进行单元测试。 testFunc 调用另一个我想模拟的函数 (secondFunc)。我可以模拟 secondFunc 以便在 testFunc 的上下文中调用它时调用 secondFunc 的 spiedOn 版本吗?如果不是,我应该如何重新格式化我的 browserify 模块以使其可测试?

目前的设置看起来像这样:

app.js(浏览器模块)

module.exports = (function () {
    function testFunc() {
        secondFunc();
    }

    function secondFunc(){
        console.log('not mocked!');
    }

    return {
        testFunc, secondFunc
    };

})();

test.js(茉莉花测试)

describe("testFunc", () => {
    let app = require('./app');

    beforeEach(() => {
        spyOn(app, 'secondFunc');
    });

    it("should call secondFunc spy", () => {
        app.testFunc();
        expect(app.secondFunc).toHaveBeenCalled();
    });

});

发生这种情况的原因是因为您在返回的对象上设置了模拟,但代码正在调用内部函数。我过去所做的是这样的:

module.exports = (function () {
    function testFunc() {
        api.secondFunc();   // Call the API function, which is what is mocked
    }

    function secondFunc(){
        console.log('not mocked!');
    }

    var api = {
        testFunc, secondFunc
    };

    return api;

})();

你现在的方式是,spyOn 用代理替换你返回的对象上的 secondFunc 属性,但你的代码调用 secondFunc 函数那是在匿名函数的闭包中。有多种方法可以重构代码以更好地公开函数。

您可以这样构建您的模块:

exports.testFunc = function() {
    exports.secondFunc();
}

exports.secondFunc = function(){
    console.log('not mocked!');
}

它更小,更容易阅读,并且让你模拟 secondFunc 函数。