Skip to content

mocha-chain ​

npm · Source · Changelog

Chain Mocha hooks so each one passes typed context to the next, instead of sharing nullable variables between them.

ts
import { 
expect
} from 'chai';
import {
beforeEach
,
suite
} from 'mocha-chain';
suite
('Counter', () => {
const
withCounter
=
beforeEach
(() => ({
counter
: new
Counter
() }));
withCounter
.
test
('starts at zero', ({
counter
}) => {
counter: Counter
expect
(
counter
.
increment
()).
to
.
equal
(1);
}); });

counter is a Counter in every test, never Counter | undefined, and each test gets a new one.

Get started →

Features ​

  • Typed context: a hook returns an object, and the hooks and tests chained to it receive it as their first parameter, merged with what earlier hooks returned.
  • Isolated tests: each test gets a shallow copy of the context, from hooks that ran for it.
  • Just Mocha: every function calls Mocha's own, so this.timeout(), .only(), .skip(), retries and reporters all work, and native Mocha calls can be mixed in.
  • Catches misplaced tests: a test or hook declared inside another test or hook throws, where Mocha would silently ignore it.
  • Teardown with the same context: afterEach and after receive what setup returned, so cleanup is typed too.
  • For Vitest too: vitest-chain is the same API for Vitest.

Compared to ​

  • Plain Mocha: a let variable assigned in beforeEach must be typed T | undefined, and asserted non-null in every test. See Why mocha-chain.
  • mocha-typescript and similar class-based wrappers give tests typed fields through decorators and class instances. mocha-chain keeps Mocha's functional style, and needs no decorators.
  • Vitest's test context (test.extend) types fixtures for Vitest. vitest-chain brings the hook-based style to Vitest instead.

Packages

  • vitest-chain

    The same hook chaining for Vitest, with typed context alongside Vitest’s own test context.

  • pg-dolly

    A fresh Postgres database for every test, cloned from a template built once from your schema’s SQL, safe next to dev data and across parallel runs.

Used in demos

  • Read-through cache

    BentoCache on Valkey: a memory tier kept in sync, stale-while-revalidate, one load per key across instances, and sharding over several nodes with weighted rendezvous hashing.

  • OpenAPI

    A notes API from spec to database: an OpenAPI 3.1 document built from Juniper schemas, genever types for a typed client and a Hono server that validates every request and response, and Drizzle on Postgres with a database per test.

  • MCP server

    Making the notes API easy for AI agents that connect to services: tools shaped for tasks, an OAuth resource server with step-up scopes, and token exchange to call the API as the agent’s user.

  • CLI for agents

    Making the notes API easy for AI agents with a shell: one short command per task, logging in once from the API’s URL, with tokens, refresh and errors handled inside.

  • Dev OAuth server

    oidc-provider as a local authorization server: the real OAuth 2.1 flow with a fake login, so the other demos test their auth end to end.