1

I am trying to spy on a global function e.g.

function foo() {

}

but the below test is failing, how to do that

    var spy = sinon.spy(foo);
    foo();
    expect(spy.callCount).to.equal(1);

** EDIT **

If I do it like below then it works

    var spy = sinon.spy(window, "foo");
    foo();
    expect(spy.callCount).to.equal(1);

So whats the difference

harishr
  • 17,807
  • 9
  • 78
  • 125
  • 1
    I've left an answer, if there is anything you would like for me to clarify please let me know. If the problem is resolve, indicate so by marking as answer. – EyuelDK May 20 '17 at 05:28

1 Answers1

4

Using var spy = sinon.spy(foo); doesn't wrap the function foo as you might think. It actually returns a spy that contains the wrapped function.

Using var spy = sinon.spy(window, "foo"); actually wraps the foo method. Internally, window["foo"] = <wrapped function> is being done, thus replacing your the function referenced by foo to the wrapped function.

For var spy = sinon.spy(foo); to work you must not call foo() instead you need to call spy()

function foo() {

}

console.log('BEGIN sinon.spy(foo)');
var spy = sinon.spy(foo);
spy();
foo(); // called foo, but no effect on callCount
foo(); // called foo, but no effect on callCount
foo(); // called foo, but no effect on callCount
console.log('Call Count:', spy.callCount);

console.log('BEGIN sinon.spy(window, \'foo\')');
var spy = sinon.spy(window, 'foo');
spy();
foo(); 
foo(); 
foo();
console.log('Call Count:', spy.callCount);
<script src="https://cdnjs.cloudflare.com/ajax/libs/sinon.js/1.15.4/sinon.min.js"></script>
EyuelDK
  • 3,029
  • 2
  • 19
  • 27
  • thanks for the answer. btw, why not `window.foo` and why `window, "foo"` – harishr May 20 '17 at 05:39
  • 1
    the `spy` function needs to know the object and the method of that object to spy on. As I said in my answer, internally it is doing something like `object[method] = wrapped(object[method])` In javascript, you technically can't overwrite a function, but rather you redirect the reference of the function. The function referenced by `foo` is never changed, but the function referenced by the variable `foo` is changed, i.e. by the use of the object and method of the object. – EyuelDK May 20 '17 at 05:43
  • thanks a lot for great explanation.. that nailed it for me :) – harishr May 29 '17 at 04:14