nodejs覆盖模块中的函数

时间:2014-09-03 16:15:10

标签: node.js

我正在尝试测试模块中的函数。此函数(我将其称为function_a)在同一文件中调用不同的函数(function_b)。所以这个模块看起来像这样:

//the module file

module.exports.function_a = function (){ 
  //does stuff
  function_b()
};

module.exports.function_b = function_b = function () {
  //more stuff
}

我需要使用function_b中的特定结果测试function_a。

我想从我的测试文件中覆盖function_b,然后从我的测试文件中调用function_a,导致function_a调用此覆盖函数而不是function_b。

只是一个注释,我已尝试并成功地从单独的模块中覆盖函数,例如this问题,但这不是我感兴趣的内容。

我已经尝试过下面的代码,据我所知,它不起作用。它确实说明了我的目标。

//test file
that_module = require("that module")
that_module.function_b = function () { ...override ... }
that_module.function_a() //now uses the override function

有没有正确的方法呢?

2 个答案:

答案 0 :(得分:7)

从模块的代码外部,您只能修改该模块的exports对象。您无法“进入”模块并更改模块代码中function_b的值。但是,您可以(在最后一个示例中)确实更改了exports.function_b的值。

如果您更改function_a来呼叫exports.function_b而不是function_b,则您对该模块的外部更改将按预期进行。

答案 1 :(得分:3)

您实际上可以使用软件包rewire。它允许您获取并设置模块中声明的内容

foo.js

const _secretPrefix = 'super secret ';

function secretMessage() {
    return _secretPrefix + _message();
}

function _message() {
    return 'hello';
}

foo.test.js

const rewire = require('rewire');

// Note that the path is relative to `foo.test.js`
const fooRewired = rewire('path_to_foo');

// Outputs 'super secret hello'
fooRewired.secretMessage();

fooRewired.__set__('_message', () => 'ciao')

// Outputs 'super secret ciao'
fooRewired.secretMessage();