Node.js如何覆盖模块中的函数?

12

我正在尝试测试一个模块中的函数。这个函数(我将它称为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。

请注意,我已经尝试并成功地覆盖了来自不同模块的函数,例如这个问题,但那不是我感兴趣的。

我尝试了下面的代码,据我所知,它不能工作。但它确实说明了我的意图。

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

有没有正确的方法来完成这个任务?

2个回答

14

从模块代码的外部,你只能修改该模块的 exports 对象。你不能“插手进去”并更改模块代码中的 function_b 值。然而,你可以(并且在最后一个示例中已经做到了)更改 exports.function_b 的值。

如果你将 function_a 改为调用 exports.function_b 而不是 function_b,则你对模块的外部更改将按预期发生。


4

你实际上可以使用包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();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接