Problem, as an interviewer would state it:
"Implement a minimal createSpy(implementation) — like jest.fn() — that wraps a function, RECORDS every real call's arguments and return value, and supports mockReturnValue, toHaveBeenCalledWith, and toHaveBeenCalledTimes."
Examples:
const add = createSpy((a, b) => a + b);
add(2, 3);
add.toHaveBeenCalledWith(2, 3); // true
Clarifying questions expected:
- Should the spy still call the REAL wrapped implementation by default, or only ever track calls without invoking anything?
- Does mockReturnValue need to override the real implementation entirely, regardless of the arguments the spy is called with?
- Should call arguments be compared by DEEP equality for toHaveBeenCalledWith, not just reference equality?
Code / implementation expected: Yes — real, direct proof that the spy correctly forwards to a real implementation, records real calls, and correctly answers toHaveBeenCalledWith/Times queries, plus mockReturnValue overriding real behavior.