I'm unable to spy on an existing function in the current scope within 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
I can however spy on a function which is a member of an object:
var anObject = {
myFunc: function() {console.log('Being spied on turns me on');}
};
sinon.spy(anObject, 'myFunc');
sinon.myFunc.restore(); // smooth sailing
According to the docs , it seems to me like that should work fine. How do I get this done?
In JavaScript when a function
is passed as an argument it is a reference-passed-by-value, like so:
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();
This will print out "foo"
, not "bar"
, because mutatate
does not change foo
's reference to func1
.
Here is the relevant source code for Sinon's spy.js
: https://github.com/sinonjs/sinon/blob/master/lib/sinon/spy.js
The create
function sees if the first argument is a function, and if so, it wraps it in a proxy ( create: function create(func, spyLength) {
, line 148). It then returns the proxy.
So in your case, you need to replace myFunc
with the new proxy:
function myFunc() {console.log("Spy on me and I'll have you arrested"};
myFunc = sinon.spy(myFunc); // here
However you cannot use myFunc.restore()
to undo the spy because .restore
cannot change the target of the myFunc
reference. Note that restore
also does not return a value, so you must keep track of myFunc
yourself:
function myFuncOriginal() {console.log("Spy on me and I'll have you arrested"};
var myFunc = sinon.spy(myFuncOriginal);
myFunc = myFuncOriginal; // instead of `myFunc.restore();`
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.