Skip to content

Comparison

How vitest-auto-spy compares to other mocking / auto-spy libraries. The niche: the only auto-spy library that reads a class and gives a fully-typed spy of every method with return-type-aware control helpers — across any Vitest-compatible runtime and framework.

LibraryReads a class?Return-type-aware helpers?RuntimeWe win on
jest-auto-spiesJest onlyVitest/Bun/node:test successor, same API — direct migration path.
@bugsplat/vitest-auto-spiesVitest onlySame class-based API plus Bun & node:test, type-only createAutoMock, framework recipes, console spies, and zero runtime deps (it depends on @hirez_io/auto-spies-core; rxjs < 8 cap — we support rxjs 8).
vitest-mock-extended❌ (Proxy)VitestReturn-type ergonomics and reading a real class. Its type-only mode is matched by createAutoMock / mockDeep, with the helpers kept.
@golevelup/ts-vitestpartialVitestTyped Promise/Observable helpers + explicit class→spy + mustBeCalledWith.
ts-auto-mock❌ (transform)Jest/tsNo compiler transformer to install — runtime-only, no toolchain coupling.
sinon❌ (manual)AnyAuto-generated + fully typed vs manual + loosely typed.
testdouble.jspartialAnyStronger typing, return-type-aware helpers, framework recipes.

Pitch: the only auto-spy library that reads a class and gives a fully-typed spy of every method with return-type-aware control helpers (resolveWith / nextWith / calledWith) — across any Vitest-compatible runtime and framework.

Feature by feature

vitest-auto-spyjest-auto-spiesvitest-mock-extended@golevelup/ts-vitestsinon
Spy every method of a class in one callpartial
Mock from a type/interface
Recursive deep mock
Spy-free data double (createMock)
resolveWith / rejectWith
nextWith / nextWithValues (RxJS)
calledWith / mustBeCalledWithcalledWith
Getter / setter spies
Vitest
Bun (bun:test)partial
node:testpartial
Angular TestBed under bun test
Runtime dependencies01104

Dependency counts are each package's own dependencies on npm, checked 2026-08-26 — @hirez_io/auto-spies-core for jest-auto-spies, ts-essentials for vitest-mock-extended, and four @sinonjs/* + diff packages for sinon.

Beyond the class spy

The tables above compare the part every one of these libraries does. What none of the others ship alongside it:

  • Angular's TestBed under bun test — Bun ships no DOM and cannot resolve templateUrl, so Angular specs do not run there at all. One preload closes both gaps.
  • renderShallow and createWithAutoSpies — the shallow-TestBed copy-paste and DI-driven instantiation as one call each.
  • stable / flushEffects and toHaveSignalValue — zoneless waiting and a signal matcher, for a codebase where detectChanges() is no longer enough.
  • Observable assertions that fail when the stream stays silent, duck-typed so they pull in no rxjs.
  • setupFakeTimers() / advanceTimers() — an advance that also drains the microtasks a bare advanceTimersByTime() leaves pending, and flushEventLoop / settleDynamicImport for the queue the clock does not reach at all.
  • mockConstructor / stubConstructor — a double the code under test can call with new, which a runner's own vi.fn(() => instance) is not.
  • fakeAsync and waitForAsync on Vitestzone.js/testing installs its ProxyZone through Jasmine and Jest hooks only, so both throw until this patch is imported.
  • assertMocked / moduleNamespace — proof that a vi.mock() actually applied under a bundler, instead of a spec quietly asserting on the real module.
  • setupAutoSpy({ strayRejections: true }) — the promise rejections zone.js drains into console.error and no further, turned into failed tests. Nothing else on this list looks there: a swallowed rejection never reaches the channel Vitest watches, so a spec that asserts inside a .then() nobody awaits stays green and exits 0.
  • setupAutoSpy({ pruneMockRegistry: true }) — the Set inside @vitest/spy that every vi.fn() joins and that nothing ever takes anything out of, kept to the mocks that outlive a file. On isolate: false it is what makes clearMocks cost more with every test already run, and what keeps a whole run's recorded arguments — and the component trees behind them — alive in one worker.
  • Twelve ESLint rules versioned together with the API they recommend, and setupAutoSpy() for the test-run hygiene a shared environment needs.
  • Per-file TestBed diagnostics — which specs actually pay for TestBed, and by how much.
  • compareTestRuns — whether the migration that brought you here lost a test, from the two sets of names rather than from two totals that happen to match.

Where another library is the better answer

  • You are on Jest and staying there. jest-auto-spies is the same API; there is nothing to gain from switching runner just for this.
  • You only ever mock interfaces, never classes, and want nothing else.vitest-mock-extended is smaller and does exactly that. createAutoMock / mockDeep cover the same ground here if you want the helpers too — the two are complementary, not exclusive.
  • You need sandboxes, fake servers, or a full test-double toolkit. sinon is a wider tool; this package is deliberately only about turning a type or a class into a typed spy.

Released under the MIT License.