Sinon stub function used with destructuring

江枫思渺然 提交于 2019-11-27 22:29:34

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());

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!

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.

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.

In essence:

This will be affected by stubbing

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

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

This will not be affected by stubbing

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

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

Since your module returns an object and theMethodIwant is property of that object you can define your stub like this:

const myModule = require('path/to/module')
myModule.theMethodIwant = sinon.stub()
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!