Spy And Stub Test Recorder

A tiny dependency-free spy that records calls, supports return stubs and resolved values, and resets between tests.

JavascriptData Integrity

Code

snippet
export function createSpy(implementation = () => undefined) {
  if (typeof implementation !== "function") {
    throw new TypeError("implementation must be a function");
  }
  let behavior = implementation;
  const calls = [];
  const spy = function spyWrapper(...args) {
    const call = { args, thisArg: this, result: undefined, error: undefined };
    calls.push(call);
    try {
      call.result = behavior.apply(this, args);
      return call.result;
    } catch (error) {
      call.error = error;
      throw error;
    }
  };
  spy.calls = calls;
  spy.callCount = () => calls.length;
  spy.calledWith = (...expected) => calls.some((call) => {
    return expected.every((value, index) => Object.is(value, call.args[index]));
  });
  spy.mockImplementation = (next) => {
    if (typeof next !== "function") throw new TypeError("next must be a function");
    behavior = next;
    return spy;
  };
  spy.mockReturnValue = (value) => {
    behavior = () => value;
    return spy;
  };
  spy.mockResolvedValue = (value) => {
    behavior = () => Promise.resolve(value);
    return spy;
  };
  spy.reset = () => {
    calls.length = 0;
    behavior = implementation;
    return spy;
  };
  return spy;
}