无法监视现有功能

时间:2016-06-25 23:36:50

标签: javascript node.js sinon spy

我无法监视node.js中当前范围内的现有函数:

function myFunc() {console.log("Spy on me and I'll have you arrested"};
sinon.spy(myFunc);
myFunc.restore(); // throws an error: myFunc.restore is not a function

然而,我可以监视作为对象成员的函数:

var anObject = {
  myFunc: function() {console.log('Being spied on turns me on');}
};
sinon.spy(anObject, 'myFunc');
sinon.myFunc.restore(); // smooth sailing

根据the docs,在我看来,这应该可以正常工作。我该如何完成这项工作?

1 个答案:

答案 0 :(得分:1)

在JavaScript中,function作为参数传递时,它是一个引用传递值,如下所示:

function foo() { console.log("foo"); } // func1, referenced by `foo`
function bar() { console.log("bar"); } // func2, referenced by `bar`

function mutate(func) {
    func = bar;
}

mutate( foo );
foo();

这将打印出"foo",而不是"bar",因为mutatate不会更改foofunc1的引用。

以下是Sinon spy.js的相关源代码:https://github.com/sinonjs/sinon/blob/master/lib/sinon/spy.js

create函数查看第一个参数是否为函数,如果是,则将其包装在代理(create: function create(func, spyLength) {,第148行)中。然后它返回代理。

因此,在您的情况下,您需要使用新代理替换myFunc

function myFunc() {console.log("Spy on me and I'll have you arrested"};
myFunc = sinon.spy(myFunc); // here

但是,您无法使用myFunc.restore()撤消间谍,因为.restore无法更改myFunc引用的目标。请注意,restore也不会返回值,因此您必须自己跟踪myFunc

function myFuncOriginal() {console.log("Spy on me and I'll have you arrested"};
var myFunc = sinon.spy(myFuncOriginal);
myFunc = myFuncOriginal; // instead of `myFunc.restore();`