Solution
- Let's create a
spyOn function which takes two arguments:
obj - the object containing the method to be spied on
methodName - a string representing the name of a method
- Let's initialize an array
calls, which is used to store the arguments with which the spied method is called.
- Create
originMethod which will be the reference to the original method from the object. This is necessary to maintain the original functionality of the method while adding the spy capability.
- Ensure that the specified
methodName corresponds to a function in the object. If not, an error is thrown. This is a safeguard to prevent incorrect usage of the spyOn function.
- The original method on the object is then overridden with a new function. This new function does two things:
- It records the arguments passed to the method call in the
calls array.
- It calls the original method using
apply to ensure that the context (this) and arguments are passed correctly.
- Finally, the
spyOn function returns an object containing the calls array. This allows the user of the function to inspect the arguments with which the spied method has been called.
Code
function spyOn(obj, methodName) {
const calls = [];
const originMethod = obj[methodName];
if (typeof originMethod !== "function") {
throw new Error("not function");
}
obj[methodName] = function (...args) {
calls.push(args);
return originMethod.apply(this, args);
};
return {
calls,
};
}