function spyOn (func) { this.func = func; this.func.counter = 0; this.func.counter++; this.func.callCount = function () { return this.counter; } this.func.returned = function () { return 'returned'; } this.func.wasCalledWith = function () { return 'calledWith'; } return this.func; } function returns1 () { return 1; } var spy = spyOn(returns1); console.log(spy.callCount());//0 console.log(spy.returned(1));//false console.log(spy.wasCalledWith('hello'));//false spy('hello', 'hi', 'howdy'); spy('goodbye', 'bye', 'see ya'); console.log(spy.callCount()); //2 console.log(spy.returned(1));//true console.log(spy.wasCalledWith('hi'));//true console.log(spy.wasCalledWith('bye'));//true 

3 methods should work.

  1. callCount returns the number of times spyOn was called, my counter is reset every time.
  2. returned (x) returns true if spyOn ever returned x.
  3. wasCalledWith (x) returns true if spyOn has ever been invoked with argument x.

    1 answer 1

     function spyOn(func) { let calls = 0 let all = [] let val const spy = function(...args) { calls++ all.push(...args) val = func.apply(this, args) return val } spy.callCount = () => calls spy.wasCalledWith = (x) => all.some((a) => x === a) spy.returned = (x) => x === val return spy } 
    • second point is not fulfilled - Grundy