代码之家  ›  专栏  ›  技术社区  ›  J.R.

sinon存根未替换函数。

  •  16
  • J.R.  · 技术社区  · 6 年前

    我尝试了一个虚拟模块并将其存根,但没有成功。

    应用程序。js公司

    function foo()
    {
        return run_func()
    }
    function run_func()
    {
        return '1'
    }
    exports._test = {foo: foo, run_func: run_func}
    

    测试。js公司

    app = require("./app.js")._test
    describe('test', function(){
        it('test', function(){
    
            var test_stub = sinon.stub(app, 'run_func').callsFake(
              function(){
                return '0'
            })
            test_stub.restore()
    
            var res = app.foo()
            assert.equal('0', res)
        })
    })
    

    我尝试了以下建议: sinon stub not replacing function

    但还是一样。它不会取代该功能。

    1 回复  |  直到 6 年前
        1
  •  27
  •   sripberger    6 年前

    你这里有几个问题。首先是你在打电话 test_stub.restore() 创建存根后,它会立即用原始函数替换自身,从而有效地完全撤消存根。

    restore 是用来清除假方法的 之后 你的测试完成了。所以你确实想叫它,但你应该在 afterEach.

    你的第二个问题有点微妙。Sinon的工作方式是覆盖对对象上函数的引用,使其指向其他对象(在本例中是存根)。它不能在其他上下文中替换对同一函数的引用。

    当你打电话的时候 sinon.stub(app, 'run_func') ,有点像这样:

    app.run_func = sinon.stub()
    

    ... 除了前一种方式存储 app.run_func ,允许您稍后轻松恢复。

    请注意,此时,变量 app 指向导出时使用的同一对象 exports._test = {foo: foo, run_func: run_func} 你的 foo 但是,函数未引用 run_func 通过此对象。它直接在 app.js ,这是sinon无法影响的。

    请看下面的示例。你还会注意到我还清理了其他一些东西:

    应用程序。js公司:

    exports.foo = function() {
        return exports.run_func();
    };
    
    exports.run_func = function() {
        return '1';
    };
    

    测验js公司:

    const app = require('./app');
    const sinon = require('sinon');
    
    describe('app', function() {
        describe('foo', function() {
            beforeEach(function() {
                sinon.stub(app, 'run_func').returns('0');
            });
    
            afterEach(function() {
                app.run_func.restore();
            });
    
            it('returns result of app.run_func', function() {
                assert.equal(app.foo(), '0');
            });
        });
    });
    

    注意如何 exports 在里面 应用程序。js公司 指的对象与 应用程序 在中执行 test.js . 这是因为节点中的模块默认导出一个空对象,您可以通过 出口 变量