В 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
не меняет foo
Ссылка на func1
.
Вот соответствующий исходный код для Синона 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();`
'restore' не будет работать здесь - шпион не может мутировать родительскую сферу таким образом (' restore' работает только для конструктора 'spy (object, methodname)'). –
@SeanVieira Спасибо, я улучшил свой ответ. – Dai