与解构一起使用的 Sinon 存根函数 [英] Sinon stub function used with destructuring

查看:27
本文介绍了与解构一起使用的 Sinon 存根函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望存根我当前正在测试的文件中使用的函数.像这样的解构需要这个函数:

I wish to stub a function used in the file I'm currently testing. This function is required with a destructuring like this:

 const { theFunctionIWant } = require('path/to/module')

测试时,从不调用存根,而是继续调用真正的函数.但是当我正常"需要它时(即:没有解构)

When testing, the stub is never called, and the real function proceed to be called. But when I require it 'normally' (i.e: without destructuring)

const myModule = require('path/to/module')

然后正确使用存根,一切正常

then the stub is correctly used and everything works fine

我感觉这是因为解构的工作方式以及 sinon 存根对象属性而不是直接存根函数的事实.无论如何,如果您能给我提供一些见解,我将不胜感激!

I sense that it's because of how the destructuring works and the fact that sinon stub the object property and not the function directly. Anyhow if you can provide me some insights I will be grateful !

推荐答案

当从依赖模块使用解构时,对模块的方法进行存根不起作用的原因很简单,与绑定实际的时间有关功能参考.它与 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()
}

这篇关于与解构一起使用的 Sinon 存根函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆