覆盖node.js中其他模块中的函数

时间:2012-10-19 05:55:25

标签: javascript node.js stub stubbing nodeunit

我正在尝试在Node.js应用中使用nodeunit存根函数。这是我正在尝试做的简化版本:

lib/file.js

var request = require('request');

var myFunc = function(input, callback){
    request(input, function(err, body){
        callback(body);
    });
};

test/test.file.js

var file = require('../lib/file');

exports['test myFunc'] = function (test) {
    request = function(options, callback){
        callback('testbody');
    };

    file.myFunc('something', function(err, body){
        test.equal(body, 'testbody');
        test.done();
    });
};

似乎我没有正确地覆盖request,因为当我尝试运行测试时,实际的非存根request被调用,但我无法弄清楚是什么正确的方法是。

编辑:

通过上面的例子,扩展Ilya的答案。

lib/file/js中的

module.exports = function(requestParam){
    return {
        myFunc: function(input, callback){
            requestParam(input, function(err, body){
                callback(body);
            });
        }
    }
}

然后在test/test.file.js

var fakeRequestFunc = function(input, callback){
// fake request function
}

var file = require('../lib/file')(fakeRequestFunc)(
//test stuff
}

2 个答案:

答案 0 :(得分:3)

正如您所注意到的,在一个模块中声明的变量无法从另一个模块轻松访问。在这种情况下,您有两种常见的变体:

1)在每个模块中声明你需要的一切(不是你的情况,我想)

2)将参数传递给函数

var ab = "foo",
index = require('/routes/index')(ab);

当您通过模块调用函数时,您可以传递“请求”或您需要的任何其他变量或对象。

答案 1 :(得分:2)

我遇到了类似的问题。在探索request模块代码后,我的解决方案在我的代码中使用request.get而不是request(完全相同)。然后将其存储在测试中:https://github.com/anatoliychakkaev/resizer-app/blob/master/test/resizer.js#L25

还可以在nodejs中存储'require'方法的结果。检查lib / module.js上的源代码以管理如何执行此操作。它应该是这样的:

require('module')._cache['/path/to/request.js'] = your_stub

但是我不喜欢这个解决方案,因为它在100%的情况下都不起作用,可能会停止在未来的节点版本中工作(这不是公共API),所以你应该只在它的情况下使用这种方式不可能使用其他方法来存根。