【问题标题】:Spy on require in Node.js在 Node.js 中监视 require
【发布时间】:2013-12-19 09:22:01
【问题描述】:

在单元测试中,我想验证 SUT 是否使用特定参数调用 require。基本上我的 SUT 是一个具有以下实现的小模块:

module.exports = function () {
  require('foo');
};

我现在想写一个这样的测试:

var sut = require('./sut');
it('requires foo.', function () {
  sut();
  expect( ??? );
});

所以问题是:如何验证是否使用正确的参数调用了require?我尝试使用 Sinon.js 间谍:

var spy = sinon.spy(require);
sut();
expect(spy.callCount).to.be.equal(1);
expect(spy.calledWithExactly('foo')).to.be(true);
require.restore();

但这不起作用。当我运行测试时,Mocha 告诉我:

错误:预期 0 等于 1

我做错了什么,我该如何解决?

PS:我不需要使用 Sinon.js,所以如果另一个模块更适合我的情况,其他一切都很好。

【问题讨论】:

    标签: javascript node.js unit-testing mocha.js sinon


    【解决方案1】:

    有一个名为 proxyquire 的模块,您可以使用它覆盖依赖项以进行单元测试目的:https://npmjs.org/package/proxyquire

    您的单元测试可能如下所示:

    var proxyquire =  require('proxyquire');
    
    var sut = proxyquire('./sut', { 'foo': function(){ /* insert test code here */ });
    

    我不确定这是否正是您想要的,但也许您会发现它很有帮助。

    【讨论】:

    • proxyquire 如果我一直想要它会很棒 - 但我只需要它进行一次测试。不幸的是,使用 proxyquire,我无法为每个测试重新配置它。所以,因此:很好的提示,但不适合我的场景。
    【解决方案2】:

    你可以试试rewire。它使您可以出于测试目的私人访问模块。然后你可以检查module.children-variable 来检查依赖关系。

    如果你想检查模块 a.js 是否需要 b.js 它看起来像:

    var rewire = require("rewire");
    var a = rewire("./a.js"); // using rewire instead of require
    
    var pathToB = require.resolve("./b.js");
    var aModule = a.__get__("module"); // leaking the private module-variable
    
    assert.ok(aModule.children.some(function (module) {
        return module.filename === pathToB;
    }));
    

    【讨论】:

    • 我刚刚发现b.js不应该出现在require.cache中,否则不会出现在children-array中。
    • 如果require("./b.js")在模块启动时没有发生,你可以通过a.__set__("require", requireMock)注入你自己的require()
    猜你喜欢
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 2015-01-26
    • 2020-06-14
    • 1970-01-01
    • 2012-02-15
    • 2021-04-19
    • 2021-07-16
    相关资源
    最近更新 更多