node.js - 与解构一起使用的 Sinon stub 函数

标签 node.js unit-testing sinon

我希望对当前正在测试的文件中使用的函数进行 stub 。像这样的解构需要此函数:

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

测试时,stub 永远不会被调用,真正的函数会继续被调用。 但是当我“正常”需要它时(即:没有解构)

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

然后 stub 被正确使用,一切正常

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

最佳答案

当从依赖模块使用解构时, stub 模块的方法不起作用的原因非常简单,并且与绑定(bind)实际函数引用的时间有关。它与 CommonJS 模块、Sinon 或 Node 本身没有任何关系,所以我将从简单的 javascript 示例开始。

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 属性 stub , 直接绑定(bind)的引用仍然返回旧值!

这是因为,当 stub 时,你实际上是在赋值 对象属性的新值(函数)(此处:obj)。对该新值的新引用(使用 obj.methodFoo)将打印新值, 但如果您存储了对旧函数的引用,您将 调用旧函数时仍然得到旧的返回值。

这同样适用于您的原始问题。如果你在模块 A 中有一个依赖项 在模块 B 中的函数 foostore 该引用,然后 如果你分配一个新值(例如 stub )并不重要 导出的值,因为您已经存储了对旧值的引用。

本质上:

这会受到 stub 的影响

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

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

这不会受到 stub 的影响

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

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

关于node.js - 与解构一起使用的 Sinon stub 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52587999/

相关文章:

node.js - Node js mysqlquery 尝试添加 .then

python - 如何在 Django 测试中使用 AssertRaisesMessage()

unit-testing - 单元测试和重构现有 Grails 应用程序的策略

unit-testing - 在编写源代码之前如何编写单元测试?

javascript - 类型错误 : Attempted to wrap getRepository which is already wrapped

javascript - 如何使用 Sinon 仅模拟一种方法?

c# - 在 Visual Studio 预构建中使用 webpack

node.js - 如何全局删除已安装的 npm 包?

node.js - 亚马逊SNS确认

javascript - 尝试模拟对象实例时,Sinon stub 不起作用