问题描述
我正在尝试调用在另一个文件中定义的函数(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 中的功能上设置了间谍程序。这是因为模块的加载方式。
考虑文件的加载顺序:
- 加载
fileA
- 从
fileB
导入内容-这需要node
加载fileB
并进行设置 - 设置来自
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)
$