Sinon-监视来自不同文件的函数,该函数在另一个函数内部调用

问题描述


我正在尝试调用在另一个文件中定义的函数(funA),并且此函数在内部调用同一文件中的另一个函数(funB)。
现在,当我尝试获取funA的呼叫计数时,我得到了正确的结果。但是,对于funB并非如此,调用计数始终返回0。
这是我的代码

fileB

function funB() {

}

function funA() {
 funB();
}

module.exports = {funA,funB}


fileA

import * as fileB from "/path/to/fileB";

sinon.spy(fileB);
fileB.funA();
fileB.funA.callCount // returns 1;
fileB.funB.callCount // returns 0; // expected 1
sinon.restore();

我在做什么错了。
导入是否有点麻烦,因为我尝试使用require关键字导入,但似乎也无法正常工作。
我需要验证每次调用funA时是否使用适当的参数调用了funB。
我该怎么做到。

解决方法

我相信这里的问题是由于sinon.spy仅在文件A 中的功能上设置了间谍程序。这是因为模块的加载方式。

考虑文件的加载顺序:

  1. 加载fileA
  2. fileB导入内容-这需要node加载fileB并进行设置
  3. 设置来自fileB的功能的间谍

这里的关键步骤是#2。加载fileB并解析所有符号后,表明间谍尚未建立。因此,在funB中间对funA的引用只是对普通旧funB的引用,而不是“间谍”版本。而且,尽管您正在调用funA的“间谍”版本,但它包含对funB原始值的引用,这就是它的调用。

简而言之,sinon不会(也不能)返回并重写已经创建的引用,因此对funB的引用不会受到对sinon.spy的调用的影响。

由于两个函数都在同一个文件中,因此您不可能监视funB。一种解决方案是重组项目,使它们位于不同的文件中-这将允许您在初始化之前设置间谍。另一种解决方案是设置文件,以便您可以在运行测试之前注入funB的间谍/存根版本。

,

在您的代码中,funA始终调用原始的funB

还有另一种选择:使用object更改fileB的实现。

示例:

// File: fileB
// Create object fileB.
const fileB = {
  funB() {},funA() {
    // Note: funA calls method funB inside object fileB.
    fileB.funB();
  },}

module.exports = fileB;
// File: fileA
import sinon from 'sinon';
import fileB from './fileB';
// This spy will replace all method in the object with wrapped original method.
sinon.spy(fileB);
// You call spied funA,which will call spied funB.
fileB.funA();

console.log(fileB.funA.callCount); // returns 1;
console.log(fileB.funB.callCount); // returns 0; // expected 1

sinon.restore();

结果:

$ npx mocha fileA.js
1
1


  0 passing (0ms)

$