web-dev-qa-db-ja.com

sinonスタブが関数を置き換えていません。

ダミーモジュールを試してスタブ化しようとしましたが動作しません。

app.js

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

test.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)
    })
})

私は次のアドバイスを試しました: サイノンスタブは機能を置き換えません

しかし、まだ同じです。機能を置き換えるものではありません。

8
J.R.

ここにいくつかの問題があります。 1つ目は、スタブを作成した直後にtest_stub.restore()を呼び出すことです。これにより、スタブ自体が元の関数に置き換えられ、スタブが完全に元に戻ります。

restoreは、偽のメソッドをクリーンアップするためのものですafterテストが完了しました。だからあなたはそれを呼び出したいのですが、_afterEach._で呼び出す必要があります

2番目の問題はもう少し微妙です。 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_のスコープで直接参照しているため、シノンは影響を受けません。

次の例を見てください。また、私が他のいくつかをクリーンアップしたことにも注意してください。

app.js:

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

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

test.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');
        });
    });
});
_

_app.js_のexportsが_test.js_のappとまったく同じオブジェクトを参照していることに注意してください。これは、ノードのモジュールがデフォルトで空のオブジェクトをエクスポートするためです。これは、exports変数を使用して割り当てることができます。

13
sripberger