# sinon-typed-stub

> Utility methods to better typed sinon stubs

Latest version **1.0.0** (published 2026-10-04) · MIT license · 0 weekly downloads

## Install

```sh
npm install sinon-typed-stub
pnpm add sinon-typed-stub
yarn add sinon-typed-stub
bun add sinon-typed-stub
```

## Health

**Score 65/100 (B)** — status: active.

Positive: esm support; no vulnerabilities; has provenance; recently updated; high maintenance score.

Warnings: low downloads; no types.

## Facts

| | |
|---|---|
| Version | 1.0.0 |
| Published | 2026-10-04 |
| First published | 2024-08-04 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | ESM |
| Node | >=24 |
| Dependencies | 0 |
| Unpacked size | 8.4 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 9 |
| Author | JacobLey |
| Maintainers | jacobley |
| Keywords | sinon, stub, typed |

## Links

- npm: https://www.npmjs.com/package/sinon-typed-stub
- Repository: https://github.com/JacobLey/leyman
- Homepage: https://github.com/JacobLey/leyman/tree/main/tools/sinon-typed-stub#readme
- Issues: https://github.com/JacobLey/leyman/issues
- npm.io page: https://npm.io/package/sinon-typed-stub

## Alternatives

- [pagerjs](https://npm.io/package/pagerjs.md) — 60 weekly downloads
- [whistle.savefor-mock](https://npm.io/package/whistle.savefor-mock.md) — 4 weekly downloads
- [named-patch](https://npm.io/package/named-patch.md) — 0 weekly downloads
- [@anil-labs/factory](https://npm.io/package/@anil-labs/factory.md) — 0 weekly downloads
- [@massiv-oss/grpc-fake-server](https://npm.io/package/@massiv-oss/grpc-fake-server.md) — 0 weekly downloads

## Recent versions

- 1.0.0 (latest) — 2026-10-04
- 0.0.11 — 2025-02-17
- 0.0.10 — 2025-01-05
- 0.0.9 — 2025-01-01
- 0.0.8 — 2024-12-31
- 0.0.7 — 2024-11-01
- 0.0.6 — 2024-11-01
- 0.0.5 — 2024-10-26
- 0.0.4 — 2024-10-23
- 0.0.3 — 2024-08-08
- 0.0.2 — 2024-08-04

## README

<div style="text-align:center">

# sinon-typed-stub
Type-safe wrappers for Sinon spies, stubs, and mocks.

[![npm package](https://badge.fury.io/js/sinon-typed-stub.svg)](https://www.npmjs.com/package/sinon-typed-stub)
[![License](https://img.shields.io/npm/l/sinon-typed-stub.svg)](https://github.com/JacobLey/leyman/blob/main/tools/sinon-typed-stub/LICENSE)

</div>

## Contents
- [Install](#install)
- [Example](#example)
- [Usage](#usage)
- [API](#api)
  - [stubMethod](#stubmethod)
  - [spyMethod](#spymethod)
  - [mockMethod](#mockmethod)

## Install

```sh
npm i sinon-typed-stub --save-dev
```

## Example

```ts
import { stubMethod } from 'sinon-typed-stub';

type Validator = (val: unknown) => val is number;

const stub = stubMethod<Validator>();

stub.stub.returns(false);
stub.stub.withArgs(42).returns(true);

// `stub.method` is typed as `Validator`
console.log(stub.method(42));  // true
console.log(stub.method('x')); // false

console.log(stub.spy.callCount); // 2
```

## Usage

`sinon-typed-stub` is an ESM module and must be `import`ed.

Standard Sinon `stub<Parameters, ReturnType>()` requires you to provide separate generic type parameters for parameters and return type, which is cumbersome for complex function types. `sinon-typed-stub` instead takes the full function type as a single generic, returning a typed object with `.method`, `.spy`, and `.stub` properties all inferring their types from the function signature.

The `.method` property is typed exactly as the original function type and is safe to pass as a dependency in place of the real implementation. The `.stub` property is a fully typed `SinonStub` for setting up expectations and return values.

## API

### `stubMethod<T>()`

Creates a Sinon stub typed to function type `T`. Use this to stub function dependencies that will be injected into the system under test.

**Type parameter** `T extends (...args: any[]) => unknown` — the function type to stub.

**Returns** `StubbedMethod<T>`:

| Property | Type | Description |
|----------|------|-------------|
| `.method` | `T` | The stub callable as the original function type. Pass this as a dependency. |
| `.stub` | `SinonStub<Parameters<T>, ReturnType<T>>` | Full Sinon stub for configuring behavior (`.returns()`, `.resolves()`, `.withArgs()`, etc.). |
| `.spy` | `SinonSpy<Parameters<T>, ReturnType<T>>` | Sinon spy for asserting calls (`.calledOnce`, `.calledWithExactly()`, etc.). |

```ts
import { stubMethod } from 'sinon-typed-stub';

type FetchUser = (id: string) => Promise<User>;

const fetchStub = stubMethod<FetchUser>();
fetchStub.stub.resolves({ id: '1', name: 'Alice' });

const sut = new UserService(fetchStub.method); // typed as FetchUser
await sut.getUser('1');

expect(fetchStub.spy.calledOnceWithExactly('1')).to.equal(true);
```

---

### `spyMethod<T>(fn)`

Wraps an existing function with a Sinon spy, preserving the original function type.

**Parameters**

| Parameter | Type | Description |
|-----------|------|-------------|
| `fn` | `T` | The function to wrap with a spy. |

**Returns** `SpiedMethod<T>`:

| Property | Type | Description |
|----------|------|-------------|
| `.method` | `T` | The spy callable as the original function type. |
| `.spy` | `SinonSpy<Parameters<T>, ReturnType<T>>` | Sinon spy for asserting calls. |

```ts
import { spyMethod } from 'sinon-typed-stub';

const realValidator = (val: unknown): val is string => typeof val === 'string';
const spied = spyMethod(realValidator);

spied.method('hello'); // calls real validator, returns true
expect(spied.spy.calledOnce).to.equal(true);
```

---

### `mockMethod<T>()`

Creates a Sinon mock (expectation) typed to function type `T`. Use when you need to set strict call expectations.

**Type parameter** `T extends (...args: any[]) => unknown` — the function type to mock.

**Returns** `MockedMethod<T>`:

| Property | Type | Description |
|----------|------|-------------|
| `.method` | `T` | The mock callable as the original function type. |
| `.mock` | `SinonExpectation` | Sinon expectation for `.withArgs()`, `.returns()`, `.verify()`. |
| `.stub` | `SinonStub<Parameters<T>, ReturnType<T>>` | Typed stub interface. |
| `.spy` | `SinonSpy<Parameters<T>, ReturnType<T>>` | Typed spy interface. |

```ts
import { mockMethod } from 'sinon-typed-stub';

const mocked = mockMethod<(id: string) => User>();
mocked.mock.once().withArgs('1').returns({ id: '1', name: 'Alice' });

sut.doThing(mocked.method);

mocked.mock.verify(); // asserts expectations were met
```

## Also See

- [`mocha-chain`](https://www.npmjs.com/package/mocha-chain) — type-safe Mocha hook chaining used alongside sinon-typed-stub in this repo's tests
- [Sinon.js](https://sinonjs.org/) — the underlying test double library

---
_Source: https://npm.io/package/sinon-typed-stub · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
