我可以在外部模块函数中使用sinon来调用函数调用吗?

时间:2017-06-27 14:55:26

标签: node.js sinon

我有一个模块:

let xmlParser = require('./myTools').xmlParser;

function extractDataAndWrite(xmldata) {
    let doc = xmlParser(xmldata);
    ...
}

module.exports = {
    extractDataAndWrite,
};

现在我想在xmlParser中测试extractDataAndWrite的来电:

var extractDataAndWrite = require('../services/importData.js').extractDataAndWrite;
var mytools = require('./myTools');

var sinon = require('sinon');

describe('Test extractDataAndWrite', function() {
    it('call xmlParser', function(done) {
        var xmlParserSpy = sinon.spy(mytools, 'xmlParser');

        extractDataAndWrite("someXML");

        console.log('xmlParserSpy: ' + xmlParserSpy.callCount);
        done();
    });
});

我希望得到xmlParserSpy.callCount == 1,但它是0! 我的间谍不工作,我必须改变什么?

1 个答案:

答案 0 :(得分:1)

问题是,当您在函数上创建spy时,您正在用新函数替换该函数引用。这意味着引用旧函数的人不会使用新函数。在您的情况下,事情不起作用,因为在您自己的模块已经引用旧函数引用之后,在mytools'中包装导出的函数引用。

您需要研究的一般技术称为依赖注入和链接接缝。 Sinon文档有一个good tutorial on the latter,使用proxyquire

基本上你会有这个:

const proxyquire = require('proxyquire');
const toolsStub = createToolsStub();
const importData = proxyquire('../services/importData.js', {
    './myTools': toolsStub
});

function createToolsStub(){
    return { xmlParser : sinon.stub().returns({mydoc:{foo:'bar'}};
}

然后在测试中,您可以查看xmlParser来电

assert(toolsStub.xmlParser.calledWith('arg1', 'arg2');