首页 > 解决方案 > Sinon - 从另一个函数中调用的不同文件中监视一个函数

问题描述


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

fileB

function funB() {

}

function funA() {
 funB();
}

module.exports = {funA, funB}


文件A

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。
我怎样才能做到这一点。

标签: node.jsmocha.jssinon

解决方案


I believe that the problem here is due to the fact that sinon.spy is setting up spies on the functions only in fileA. This is because of the way the modules are loaded.

Think about the order in which your files are being loaded:

  1. load fileA
  2. import stuff from fileB - this requires node to load fileB and set everything up
  3. set up the spy on functions from fileB

The key step here is #2. When fileB is loaded and all the symbols are resolved, the spies have not been set up yet. So that reference to funB in the middle of funA is just a reference to the plain old funB, not the "spied" version. And although you're calling the "spied" version of funA, it contains a reference to the original value of funB and that's what it calls.

In short, sinon does not (and cannot) go back and rewrite references that have already been created, so that reference to funB is not affected by the call to sinon.spy.

Since both functions are in the same file, there's no way you're going to be able to spy on funB. One solution would be to restructure your project so they're in different files - this would allow you to set up spies before initializing. Another solution would be to set up your file so you can inject a spy/stub version of funB before running your tests.


推荐阅读