且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Sinon存根函数与解构一起使用

更新时间:2023-09-19 11:57:16

使用从依赖模块进行解构时,对模块方法进行存根的原因很简单,并且与绑定实际模块的时间有关功能参考.它与CommonJS模块(Sinon或Node本身)没有任何关系,因此我将以简单的JavaScript示例开始.

The reason stubbing the method of the module doesn't work when using destructuring from a dependant module is quite simple and has to do with the time you bind the actual function reference. It doesn't have anything to do with CommonJS modules, Sinon or Node per se, so I'll start out with simple javascript examples.

const stub = (o, method) => (o[method] = () => "I am a stub");

const obj = {
  methodFoo() {
    return "I am foo";
  }
};

// same as doing `const methodFoo = obj.methodFoo;`
const { methodFoo } = obj; // "import" using destructuring

console.log("obj.methodFoo(): ", obj.methodFoo());
console.log("methodFoo()", methodFoo());

console.log("Stubbing out method!");
stub(obj, "methodFoo");

console.log("obj.methodFoo: ", obj.methodFoo());
console.log("methodFoo()", methodFoo());

如果运行上面的示例,即使 您已将obj模块"的methodFoo属性存根, 直接绑定的引用仍然返回旧值!

If you run the example above, you will see that even though you have stubbed the methodFoo property of the obj "module", the directly bound reference still returns the old value!

这是因为,在进行存根时,您实际上是在分配 对象属性(此处为obj)的新值(函数).对此新值的新引用(使用obj.methodFoo)将打印新值, 但是如果您已经存储了对旧功能的引用,您将 调用旧函数时仍会获得旧的返回值.

This is because, when stubbing you are essentially assigning a new value (a function) to a property of an object (here: obj). New references to this new value (using obj.methodFoo) will print the new values, but if you have stored a reference to the old function you will still get the old return values when calling the old function.

这同样适用于您的原始问题.如果您在模块A中具有依赖项 在模块B中的函数foo store 上进行引用,然后 是否分配新值(例如存根)都没有关系 导出的值,因为您已经存储了对旧值的引用.

The same applies to your original problem. If you in module A have a dependency on a function foo in module B and store that reference, then it doesn't matter if you assign a new value (for instance a stub) to the exported value, since you already stored a reference to the old value.

本质上:

这将受到存根的影响

const A = require('./A');

function doFoo(){
    A.foo(); // will always evalute  A['foo']()
}

这不会受到存根的影响

const myFoo = require('./A').foo;

function doFoo(){
    myFoo(); // will just evalute to the original value of A.foo()
}