CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-sinon

JavaScript test spies, stubs and mocks for framework-agnostic unit testing.

Pending
Overview
Eval results
Files

fakes.mddocs/

Fake Functions

Fake functions are a simpler alternative to spies and stubs, providing call recording with optional custom implementations. They offer most spy functionality with easier creation patterns for common testing scenarios.

Capabilities

Creating Fakes

Create fake functions with optional implementations.

/**
 * Creates a fake function that records calls
 * @param func - Optional implementation function
 * @returns Fake function with spy capabilities
 */
function fake(func?: Function): SinonFake;

Usage Examples:

import { fake } from "sinon";

// Empty fake (no implementation)
const callback = fake();
callback("test");
console.log(callback.called); // true

// Fake with implementation
const add = fake((a, b) => a + b);
console.log(add(2, 3)); // 5
console.log(add.calledWith(2, 3)); // true

Static Creation Methods

Convenient static methods for creating fakes with common behaviors.

declare namespace fake {
  /**
   * Creates a fake that returns a specific value
   * @param value - Value to return when called
   * @returns Fake function that returns the value
   */
  function returns(value: any): SinonFake;
  
  /**
   * Creates a fake that throws an exception
   * @param error - Error to throw (creates generic Error if omitted)
   * @returns Fake function that throws the error
   */
  function throws(error?: any): SinonFake;
  
  /**
   * Creates a fake that returns a resolved Promise
   * @param value - Value to resolve with
   * @returns Fake function that resolves with the value
   */
  function resolves(value?: any): SinonFake;
  
  /**
   * Creates a fake that returns a rejected Promise
   * @param error - Error to reject with
   * @returns Fake function that rejects with the error
   */
  function rejects(error?: any): SinonFake;
  
  /**
   * Creates a fake that calls its first callback argument
   * @param args - Arguments to pass to the callback
   * @returns Fake function that yields to callback
   */
  function yields(...args: any[]): SinonFake;
  
  /**
   * Creates a fake that calls its first callback argument asynchronously
   * @param args - Arguments to pass to the callback
   * @returns Fake function that yields to callback async
   */
  function yieldsAsync(...args: any[]): SinonFake;
}

Usage Examples:

// Fake that returns value
const getName = fake.returns("John");
console.log(getName()); // "John"

// Fake that throws error
const failingFunction = fake.throws(new Error("Operation failed"));
// failingFunction(); // throws Error: Operation failed

// Fake that resolves Promise
const fetchData = fake.resolves({ data: "success" });
const result = await fetchData();
console.log(result); // { data: "success" }

// Fake that rejects Promise
const failedFetch = fake.rejects(new Error("Network error"));
try {
  await failedFetch();
} catch (error) {
  console.log(error.message); // "Network error"
}

// Fake that calls callback
const processAsync = fake.yields(null, "processed");
processAsync((err, data) => {
  console.log(data); // "processed"
});

// Fake that calls callback asynchronously
const processAsyncDelayed = fake.yieldsAsync("result");
processAsyncDelayed((data) => {
  console.log(data); // "result" (called on next tick)
});

Fake Properties and Methods

Fakes inherit all spy properties and methods for call verification.

interface SinonFake extends SinonSpy {
  // Inherits all spy properties:
  // called, callCount, calledOnce, calledTwice, calledThrice
  // firstCall, secondCall, thirdCall, lastCall
  
  // Inherits all spy methods:
  // calledWith, calledWithExactly, alwaysCalledWith, etc.
  // calledOn, alwaysCalledOn, calledWithNew, etc.
  // threw, alwaysThrew, returned, alwaysReturned
  // getCall, getCalls, withArgs
  // resetHistory, restore, printf
}

Usage Examples:

const fake = sinon.fake();

fake("hello", "world");
fake("foo", "bar");

// Use all spy properties
console.log(fake.called); // true
console.log(fake.callCount); // 2
console.log(fake.calledTwice); // true

// Use spy methods
console.log(fake.calledWith("hello")); // true
console.log(fake.firstCall.args); // ["hello", "world"]
console.log(fake.getCall(1).args); // ["foo", "bar"]

// Filter calls
const helloFake = fake.withArgs("hello");
console.log(helloFake.callCount); // 1

Fake vs Spy vs Stub Comparison

Understanding when to use fakes instead of spies or stubs.

Usage Examples:

// Spy: Monitor existing function
const originalFn = (x) => x * 2;
const spy = sinon.spy(originalFn);
console.log(spy(5)); // 10 (original behavior)

// Stub: Replace function with programmable behavior
const stub = sinon.stub();
stub.withArgs("test").returns("result");
stub.withArgs("error").throws();

// Fake: Simple function with optional implementation
const fake = sinon.fake((x) => x + 1);
console.log(fake(5)); // 6

// Static fake creation (most convenient)
const quickFake = sinon.fake.returns("quick result");
console.log(quickFake()); // "quick result"

Integration with Objects

Using fakes to replace object methods.

Usage Examples:

// Replace object method with fake
const user = { getName: () => "John" };
user.getName = sinon.fake.returns("Jane");

console.log(user.getName()); // "Jane"
console.log(user.getName.called); // true

// Using in sandbox for automatic cleanup
const sandbox = sinon.createSandbox();
sandbox.replace(user, "getName", sinon.fake.returns("Mocked"));

console.log(user.getName()); // "Mocked"
sandbox.restore(); // Restores original method

Testing Callbacks with Fakes

Fakes are particularly useful for testing callback-based code.

Usage Examples:

// Test code that accepts callbacks
function processData(data, onSuccess, onError) {
  if (data.valid) {
    onSuccess(data.result);
  } else {
    onError(new Error("Invalid data"));
  }
}

// Test success case
const onSuccess = sinon.fake();
const onError = sinon.fake();

processData({ valid: true, result: "test" }, onSuccess, onError);

console.log(onSuccess.calledOnce); // true
console.log(onSuccess.calledWith("test")); // true
console.log(onError.called); // false

// Test error case
const onSuccess2 = sinon.fake();
const onError2 = sinon.fake();

processData({ valid: false }, onSuccess2, onError2);

console.log(onSuccess2.called); // false
console.log(onError2.calledOnce); // true
console.log(onError2.firstCall.args[0].message); // "Invalid data"

Async Testing with Fakes

Using fakes for Promise-based and async callback testing.

Usage Examples:

// Promise-based fake
const apiCall = sinon.fake.resolves({ users: [] });

async function getUsers() {
  return await apiCall("/users");
}

const users = await getUsers();
console.log(users); // { users: [] }
console.log(apiCall.calledWith("/users")); // true

// Async callback fake
const readFile = sinon.fake.yieldsAsync(null, "file contents");

function processFile(callback) {
  readFile("test.txt", callback);
}

processFile((err, data) => {
  console.log(data); // "file contents"
  console.log(readFile.calledWith("test.txt")); // true
});

Fake Lifecycle Management

Managing fake state and cleanup.

Usage Examples:

const fake = sinon.fake();

fake("first call");
fake("second call");

console.log(fake.callCount); // 2

// Reset call history
fake.resetHistory();
console.log(fake.callCount); // 0
console.log(fake.called); // false

// Fakes on object methods can be restored
const obj = { method: sinon.fake.returns("test") };
// obj.method is now a fake

// If created via sandbox or sinon.replace, restore is available
const sandbox = sinon.createSandbox();
sandbox.replace(obj, "method", sinon.fake.returns("mocked"));
sandbox.restore(); // Restores original method

Types

// Fake extends all spy functionality
interface SinonFake extends SinonSpy {
  // Inherits all SinonSpy properties and methods
  // No additional methods beyond spy interface
}

// Generic fake interface for typed functions
interface SinonFake<F extends Function = Function> extends SinonFake {
  (...args: Parameters<F>): ReturnType<F>;
}

// Static creation methods namespace
declare namespace fake {
  function returns(value: any): SinonFake;
  function throws(error?: any): SinonFake;
  function resolves(value?: any): SinonFake;
  function rejects(error?: any): SinonFake;
  function yields(...args: any[]): SinonFake;
  function yieldsAsync(...args: any[]): SinonFake;
}

Install with Tessl CLI

npx tessl i tessl/npm-sinon

docs

assertions.md

fakes.md

index.md

matchers.md

mocks.md

promises.md

sandbox.md

spies.md

stubs.md

timers.md

tile.json