DEV Community

Bukunmi Odugbesan
Bukunmi Odugbesan

Posted on

Coding Challenge Practice - Question 39

The task is to implement a spyOn function that works just like the jest.spyOn function.

The boilerplate code:

function spyOn(obj, methodName) {
  // your code here
}
Enter fullscreen mode Exit fullscreen mode

jest.spyOn wraps an existing method on an object, to track how many times it is called, the arguments it is called with, and what it returns.

If the object doesn't exist, or its property isn't a function, it stops immediately

if (!obj || typeof obj[methodName] !== "function") {
  throw new Error("Can't spy on a non-function property");
}
Enter fullscreen mode Exit fullscreen mode

Save the original method

const originalMethod = obj[methodName]
Enter fullscreen mode Exit fullscreen mode

A spy object is created, which keeps all spy data and helper methods.

const spy = {
  calls: [],
  callCount: 0,
  restore() {
    obj[methodName] = originalMethod;
  }
};
Enter fullscreen mode Exit fullscreen mode

Replace the original method, record the call data, and then call the original function. Record the return value.

obj[methodName] = function (...args) {
    spy.callCount++;      
    spy.calls.push(args);

    const result = originalMethod.apply(this, args); 
    spy.lastReturn = result; 

    return result;  
Enter fullscreen mode Exit fullscreen mode

Return the original result.

return result
Enter fullscreen mode Exit fullscreen mode

The final code

function spyOn(obj, methodName) {
  // your code here
  if(!obj || typeof obj[methodName] !== "function") {
    throw new Error("Can't spy on a non-function property")
  }

  const originalMethod = obj[methodName];

  const spy = {
    calls: [],
    callCount: 0,
    restore() {
      obj[methodName] = originalMethod;
    }
  };
  obj[methodName] = function(...args) {
    spy.callCount++;
    spy.calls.push(args);

    const result = originalMethod.apply(this, args);
    spy.lastReturn = result;

    return result;
  }
  return spy;
}
Enter fullscreen mode Exit fullscreen mode

That's all folks!

Top comments (0)