使用 SinonJS 存根(带重新布线)

Using SinonJS stub (with rewire)

我有一个函数:

var publish = function(a, b, c) {
    main = a + getWriterName(b,c);
}

getWriterName 是另一个函数:

var getWriterName = function(b,c) {
    return 'Hello World';
}

我想测试 "publish" 函数,但我不想在测试 "publish" 时 运行 "getWriterName" 函数。我觉得我存根了 getWriterName 函数,因为我不想在每次测试 "publish" 时都对它进行 运行,但我该怎么做呢?我做了类似的事情:

var sandbox = sinon.sandbox.create();
sandbox.stub(getWriterName).returns('done');

但这给了我

的错误

TypeError: Attempted to wrap undefined property undefined as function

如果我在写入路径中,我的存根有什么问题?

编辑: 我正在使用 rewire,所以想要使用 rewire

的解决方案

来自 sinon 文档:"The sinon.sandbox.create(config) method is mostly an integration feature, and as an end-user of Sinon.JS you will probably not need it."

通常您使用以下语法创建一个 sinon 存根:

sinon.stub(obj, 'property, function(){
      //do something
}

假设您在文件中的某处导出这两个函数

//somefile.js
var publish = function(a, b, c) {
    main = a + getWriterName(b,c);
}

var getWriterName = function(b,c) {
    return 'Hello World';
}
exports.getWriterName = getWriterName;
exports.publish  = publish;

在您的测试中导入它们:

var someFile = require('./somefile.js');

并尝试找出您想要的方法:

sinon.stub(someFile, 'getWriterName', function(b, c) {
    return 'done'
});

你会发现这也行不通。这是因为 sinon 实际上不能存根一个已经需要的方法,除非它可以作为你需要的文件的 属性 来访问它。为了让它工作,你需要这样做:

//somefile.js

var getWriterName = function(b,c) {
    return 'Hello World';
}
exports.getWriterName = getWriterName;

var publish = function(a, b, c) {
    main = a + exports.getWriterName(b,c);
}
exports.publish  = publish;

现在,一旦您将包含这些函数的文件导入到您的测试中,就可以访问 getWriterName 以将其删除。你会像上面的例子那样做:

sinon.stub(someFile, 'getWriterName', function(b, c) {
    return 'done'
});

并且可以通过以下方式撤消:

someFile.getWriterName.restore();

这解决了我的问题:

如果我的函数在一个名为 main.js 的文件中,那么我首先将文件重新连接为:

var main = rewire('main');

然后在一个函数中调用任何其他函数,在我的例子中,当我必须存根时 getWriterName 我会做:

main.__set__('getWriterName', function(b, c) {
    return 'Something Else'
}

最后在使用完后,做

main.restore();

这就是将 Sinon 与 Rewire 一起用于存根函数的方式。如果存根函数是私有的,那么 Rewire 在这种情况下特别有用。

it('getWriteName always returns "Hello World"', function() {      
    var stub = sandbox.stub();
    stub.returns('Hello World');
    var unset = log.__set__('getWriterName', stub);

    // your test and expectations here

    unset();
    // it's always good to restore the previous state
});