3

我正在尝试在 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
}
4

2 回答 2

3

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

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

2) 将参数传递给函数

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

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

于 2012-10-19T06:04:38.013 回答
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),所以只有在不可能的情况下才应该使用这种方式使用其他的存根方法。

于 2012-10-19T10:45:29.590 回答