Node.js Sinon stub不';当使用对象解构时,它似乎不起作用

Node.js Sinon stub不';当使用对象解构时,它似乎不起作用,node.js,sinon,Node.js,Sinon,假设在模块myModule中有一个名为myMethod的方法,如下所示: function myMethod() { return 5; } module.exports.myMethod = myMethod; 现在如果我想用Sinon将这个方法存根为返回2而不是5,我会写 const myModule = require('path/myModule'); sinon.stub(myModule, 'myMethod').returns(2); 现在,在您实际调用方法的地方,您碰巧

假设在模块
myModule
中有一个名为
myMethod
的方法,如下所示:

function myMethod() {
   return 5;
}
module.exports.myMethod = myMethod;
现在如果我想用Sinon将这个方法存根为返回2而不是5,我会写

const myModule = require('path/myModule');
sinon.stub(myModule, 'myMethod').returns(2);
现在,在您实际调用方法的地方,您碰巧导入了这样的方法,并销毁了对象

const { myMethod } = require('path/myModule');
console.log(myMethod()); // Will print 5
如果您这样做,
myMethod
实际上并没有存根,并且不会返回2,而是返回5

如果您再次需要该模块并使用所需模块中的功能,则该模块将正常工作

const myModule= require('path/myModule');
console.log(myModule.myMethod()); // Will print 2

除了改变我导入函数的方式之外,还有人能解决这个问题吗?

存根
myMethod
的引用将与原始方法不同。在解构示例中,您正在设置引用,然后才能将其存根

// cannot be stubbed
const { myMethod } = require('path/myModule');

// can be stubbed
const myModule = require('path/myModule');
myModule.myMethod();

查看类似问题以了解更多详细信息

存根的
myMethod
将有一个与原始方法不同的参考。在解构示例中,您正在设置引用,然后才能将其存根

// cannot be stubbed
const { myMethod } = require('path/myModule');

// can be stubbed
const myModule = require('path/myModule');
myModule.myMethod();
查看类似问题以了解更多详细信息

这是可能的

请注意,一旦运行此命令:

const{myMethod}=require('./lib');
…它将记住当时的
myMethod
是什么

因此,您只需确保在代码运行之前设置存根


所以对于这个
lib.js

函数myMethod(){
返回5;
}
module.exports.myMethod=myMethod;
这个
code.js

const{myMethod}=require('./lib');
log(myMethod());
您只需执行以下操作:

const sinon=require('sinon');
常量myModule=require('./lib');
sinon.stub(myModule,'myMethod')。返回(2);//首先设置存根。。。
需要(“./代码”);/。。。然后需要代码(打印“2”)
这是可能的

请注意,一旦运行此命令:

const{myMethod}=require('./lib');
…它将记住当时的
myMethod
是什么

因此,您只需确保在代码运行之前设置存根


所以对于这个
lib.js

函数myMethod(){
返回5;
}
module.exports.myMethod=myMethod;
这个
code.js

const{myMethod}=require('./lib');
log(myMethod());
您只需执行以下操作:

const sinon=require('sinon');
常量myModule=require('./lib');
sinon.stub(myModule,'myMethod')。返回(2);//首先设置存根。。。
需要(“./代码”);/。。。然后需要代码(打印“2”)

所以,在这种情况下,由于引用不同,似乎除了重构我的导入之外没有其他方法了?我就是这样解释的,是的-您需要将解构放在更靠近函数调用的位置,而不是在模块初始化时,以便在初始化后显示对存根的引用,这是有意义的,非常感谢!“别无选择”有点太严格了。您可以将链接接缝作为目标,这意味着您可以使用proxyquire或rewire连接到模块加载中。但这与Sinon本身无关。因此,在这种情况下,似乎除了重构我的导入之外没有其他方法了,因为引用不同?我就是这样解释的,是的-您需要将解构放在更靠近函数调用的位置,而不是在模块初始化时,以便在初始化后显示对存根的引用,这是有意义的,非常感谢!“别无选择”有点太严格了。您可以将链接接缝作为目标,这意味着您可以使用proxyquire或rewire连接到模块加载中。不过,这与西农本身无关。