Spy on an existing object method
This is what jest.spyOn does. You replace a method on an object you do not own, record what it is called with while letting it behave exactly as before, and restore it when the test ends so nothing leaks into the next one. The this handling is where naive attempts break: the replacement is called as a method, so it must forward that receiver to the original or the original loses access to the object's own state.
Implement spyOn(object, methodName). It replaces object[methodName] with a wrapper that records the call and then invokes the original method with the same this and arguments, returning the original's result unchanged. It returns a spy handle with calls, an array holding one array of arguments per recorded call in order; callCount, the number of recorded calls, starting at 0; and restore(), which puts the original function back so that object[methodName] is once again the exact same function reference it was before, after which calls are no longer recorded. Spying on two different methods of the same object gives two independent handles.
Arguments
objectobject- The object whose method should be wrapped in place.
methodNamestring- The key of the method to spy on.
Returns
{ calls: any[][]; callCount: number; restore(): void } — A spy handle exposing a call log and a restore() method that puts the original function back.
Examples
const api = { total: 0, add(n) { this.total += n; return this.total; } };
const spy = spyOn(api, "add");
api.add(2); // 2 — original behaviour preserved
api.add(3); // 5
spy.calls; // [[2], [3]]
spy.callCount; // 2
spy.restore(); // api.add is the original function againconst user = { name: "Ada", greet(g) { return g + ", " + this.name; } };
const spy = spyOn(user, "greet");
user.greet("Hi"); // "Hi, Ada" — `this` still reaches the method
spy.calls; // [["Hi"]]Forwarding this from the wrapper is what keeps methods that use the receiver working.
What it has to do
- The wrapper returns the original method's result, so behaviour is unchanged.
- Invoke the original with the object as
this, so methods usingthisstill work. - Record one array of arguments per call in
calls, and keepcallCountin step. restore()puts back the identical original function reference.- Calls made after
restore()are not recorded, and two spies on one object stay independent.
Notes
- Call the original with
original.apply(this, args)from inside the wrapper — using the wrapper's ownthisis what forwards the receiver. - Save the original function reference *before* overwriting it.
restore()just assigns it back; a fresh reference would break identity checks.
Stuck? The javascript course covers everything this challenge needs.
- 1.records calls while keeping behaviour
- 2.forwards the receiver to the original method
- 3.restore puts back the original function
- 4.stops recording after restore
- 5.two spies on one object stay independent
These assertions run in your browser the moment you hit Run. Pass all of them to claim the XP.
Discussion
Sign in to postNo comments yet. Be the first to say something.