Spying on Functions
The spy() method provides functionality for creating spy wrappers around functions in JavaScript testing environments.
This module helps track function calls, arguments, and return values during test execution.
Overview
A spy wraps around an existing function, preserving all its functionality while adding instrumentation to track invocations. This is useful for verifying how functions are called in unit tests without modifying their behavior.
const sum = (a, b) => a + b;
suite('Spy Function', () => { it('Test spying', () => { const spySum = spy(sum); const result = spySum(2, 3); expect(result).toBe(5); expect(spySum.callCount).toBe(1); expect(spySum.calls[0].args).toBeArrayEqual([2, 3]); })})API Reference
spy(originalFn)
Creates a spy wrapper for the specified function.
Parameters:
originalFnfunction Function() { [native code] } - The original function to spy on
Returns:
- function Function() { [native code] } - A spy function that wraps the original while tracking calls
Properties:
original- Reference to the original functioncalls- Array of recorded calls with arguments, timestamps, and resultscallCount- Number of times the function has been calledlastCall- Information about the most recent callisMock- Boolean flag always set to true
Methods:
reset()- Clears call historyrestore()- Returns the original functionmockReturnValue(value)- Makes the spy return a specified valuerestoreBehaviour()- Restores the original function behavior after mockingcalledWith(...args)- Checks if the function was called with specified arguments
Usage Examples
Basic Usage
// Create a spy for a functionconst calculate = (a, b) => a + b;const calculateSpy = spy(calculate);
// Use the spy functioncalculateSpy(2, 3);calculateSpy(10, 5);
// Check call informationconsole.log(calculateSpy.callCount); // 2console.log(calculateSpy.calls[0].args); // [2, 3]console.log(calculateSpy.lastCall.result); // 15Mocking Return Values
const fetchData = () => fetch('/api/data');const fetchSpy = spy(fetchData);
// Override the return valuefetchSpy.mockReturnValue({ success: true, data: [1, 2, 3] });
const result = fetchSpy();console.log(result); // { success: true, data: [1, 2, 3] }
// Restore original behaviorfetchSpy.restoreBehaviour();Verifying Call Arguments
const logger = (message, level) => console.log(`[${level}] ${message}`);const loggerSpy = spy(logger);
loggerSpy("Operation completed", "INFO");loggerSpy("System error", "ERROR");
console.log(loggerSpy.calledWith("System error", "ERROR")); // trueconsole.log(loggerSpy.calledWith("Unknown message")); // falseImplementation Notes
- The spy preserves the prototype chain and properties of the original function
- Function name and other metadata are maintained when possible
- Call history includes timestamps for measuring performance
- Special care is taken to avoid copying non-copyable properties
Compatibility
Works with all JavaScript function types including:
- Named functions
- Anonymous functions
- Arrow functions
- Class methods
- Constructors (preserves prototype chain)