Skip to content

API reference ​

Every export of the package, grouped by the import path it comes from. Each row says in one line what the export does and links to the page with examples and options. New to the library? Start with the introduction; unfamiliar words are in the glossary.

A first example ​

Build a spy object from a class, set what one method answers, then check the result.

ts
import 'vitest-auto-spy/rxjs';

import { expect, it } from 'vitest';
import { createSpyFromClass, expectEmission } from 'vitest-auto-spy';

import { UserService } from './user.service';

it('answers with the user', async () => {
  const users = createSpyFromClass(UserService); // load(id: number): Observable<User>
  users.load.nextWith({ id: 1, name: 'Ada' });

  const user = await expectEmission(users.load(1));

  expect(user).toEqual({ id: 1, name: 'Ada' });
  expect(users.load).toHaveBeenCalledWith(1);
});

createSpyFromClass comes from the core. nextWith is a control helper that you call on the spied method. expectEmission waits for the stream's first value.

import 'vitest-auto-spy/rxjs' turns on nextWith and the other Observable helpers. Without it, nextWith throws Observable spies require rxjs. The import is separate so that projects without rxjs never load it. Put it at the top of each spec file that needs it, or once in the setup file (setupFiles in the Vitest config).

In an Angular TestBed spec, provideAutoSpy provides the spy and injectSpy gets it back typed Spy<UserService>. Both come from vitest-auto-spy/angular:

ts
import 'vitest-auto-spy/rxjs';

import { TestBed } from '@angular/core/testing';
import { expect, it } from 'vitest';
import { injectSpy, provideAutoSpy, stable } from 'vitest-auto-spy/angular';

import { ProfileComponent } from './profile.component';
import { UserService } from './user.service';

it('loads the user', async () => {
  TestBed.configureTestingModule({
    imports: [ProfileComponent],
    providers: [provideAutoSpy(UserService)],
  });
  const users = injectSpy(UserService);
  users.load.nextWith({ id: 1, name: 'Ada' });

  const fixture = TestBed.createComponent(ProfileComponent);
  await stable(fixture);

  expect(users.load).toHaveBeenCalledTimes(1);
});

stable waits until the component has rendered, with or without zone.js. You can also set the answer in the provider: provideAutoSpy(UserService, { returns: { load: of({ id: 1, name: 'Ada' }) } }), with of from rxjs. The method stays a spy either way, so nextWith can change the answer later.

Pick an import path ​

Each import path is an entry point. Pick the row for your test runner:

You test withImport spies fromAdd for your framework
Vitestvitest-auto-spy/angular, /nestjs, /vue, /react, /svelte
Bunvitest-auto-spy/bun/bun-angular for Angular
node:testvitest-auto-spy/node/nestjs
Rstestvitest-auto-spy/rstest/nestjs
Observable methods or propertiesalso vitest-auto-spy/rxjs (see above)—
Angular, beyond spies/angular plus /angular/matchers, /angular/doubles, …more Angular entries

On Bun, node:test or Rstest, import from the runner's entry before any other vitest-auto-spy import. The first one imported decides whose mock function the spies use. On Vitest the order does not matter.

Where createSpyFromClass and the other factories of the core can be imported from:

  • From these entries too: /bun, /node, /rstest, /react, /svelte, /vue, /bun-angular. They include everything vitest-auto-spy exports, so one import line is enough.
  • Not from any other entry, /angular and /nestjs included. A spec that uses provideAutoSpy from /angular needs no vitest-auto-spy import. A spec that also calls createSpyFromClass has two import lines. /angular does re-export a few core items: the Spy<T> type, the mock*Prop helpers and the Observable assertions.

vitest-auto-spy ​

The core. Importing it connects spies to Vitest's mock function (runner adapter).

Build a spy or a double ​

ExportWhat it doesDocs
createSpyFromClass(Class, methodsOrConfig?)Builds a typed Spy<T>: every method of the class becomes a spySpies from a class
createSpyFromInstance(instance, methodsOrConfig?)Turns the methods of an object you already have into spies, in placepassthrough
restoreSpiedInstance(instance)Puts the real methods back on that objectsame
spyOnOwnMethod(instance, method)Records one method of the object under test and still runs the real one; use it for vi.spyOnOne method
spyOnVoidMethod(target, method)Records one native void method (preventDefault, focus) without a strict-mode throwSpies from a class
createAutoMock<T>(overrides?, config?)Builds a Spy<T> from a type or interface, with no classFrom a type
autoMocked<T>(overrides?, config?)The same, typed as both T and Spy<T>, for a let set in beforeEachautoMocked
createMock<T>(partial?)Builds a plain T with no spies, for data rather than collaboratorscreateMock
mockDeep<T>(overrides?, options?)A double where a.b.c is a spy at any depth, without setupmockDeep
createFunctionSpy(name, unstubbed?)One standalone function spy with every helper; type it as FunctionSpy<Fn>One function
createSpyClass(Class, config?, options?)A spy you can call with new; records calls and instancesCall with new
mockConstructor(factory, name?)A constructor double for a class the code under test builds with newConstructor doubles
stubConstructor(target, property, factory)Replaces a global or module class with such a double, restored after the testsame
registerAutoSpyDefaults(Class, config)Registers a class's usual configuration once; every spy of that class starts from itDefaults
clearAutoSpyDefaults(Class?)Drops one registration, or all of themsame
clearAutoSpy(spy)Clears recorded calls on every spy inside the object; keeps what you configuredResetting
resetAutoSpy(spy)Clears calls and configuration, as vi.resetAllMocks() doessame

Control helpers by return type ​

A spied method gets the helpers its return type allows. They are methods of the spy (users.load.nextWith(...)), not separate exports. The Observable ones work after import 'vitest-auto-spy/rxjs'.

The methodHelpersDocs
returns a valuemockReturnValue and the runner's own mock API, calledWith(...), mustBeCalledWith(...), once(), times(n)Synchronous methods
any methodfailWith(error): throw on every call, or only for the arguments of a calledWith chainfailWith
returns Promise<T>resolveWith, rejectWith, resolveWithPerCall; outcomes land on mock.settledResultsPromise methods
returns Observable<T>nextWith, nextOneTimeWith, nextWithValues, nextWithPerCall, throwWith, complete, returnSubjectObservable methods

calledWith accepts asymmetric matchers such as expect.any(Number) at any depth; see what counts as the same argument.

Properties ​

ExportWhat it doesDocs
mockReadonlyProp(object, property, value)Sets a readonly property for one testProperty mocking
mockReadonlyPropGetter(object, property, getter)Same, with a getter functionsame
mockValueProp(object, property, value)Sets a writable property for one testmockValueProp
mockAccessorsProp(object, property, accessors?)Replaces a getter and setter pairProperty mocking
restoreMockedProps()Undoes every mock*Prop patch (and the stubs that register with it)Setup
countMockedProps()How many patches are still appliedsame
reportPropsOutsideHooks(reaction)Reports a patch made outside a test or hook, without setupAutoSpysame

Observable assertions ​

Each one subscribes for you and fails with a clear message when the stream stays silent.

ExportWhat it doesDocs
expectEmission(source$, options?)Waits for one value and returns itObservable assertions
expectEmissions(source$, count, options?)Waits for count values and returns themsame
expectAllEmissions(source$, options?)Returns every value once the stream completessame
expectNoEmission(source$, options?)Passes when nothing arrives within the waitsame
expectNoEmissionSync(source$, options?)The same check, without awaitexpectNoEmissionSync
expectCompletion(source$, options?)Passes when the stream completes, value or notexpectCompletion
expectError(source$, options?)Passes when the stream errors, and returns the errorexpectError
setEmissionTimeout(milliseconds)Changes the default wait for all of themObservable assertions

Typing, fixtures and arguments ​

ExportWhat it doesDocs
asInstance(spy) / asSpy(instance)Views a Spy<T> as T, or a T as Spy<T>, instead of as anySpy typing
asInstances(...spies)asInstance for a whole argument listasInstances
innerDouble(double, method)The spy a returnsClass method answers, read without calling the methodreturnsClass
outOfType<T>(value)A value outside T on purpose (a null the backend sends), typed TSpy typing
createFixture<T>(defaults, overrides?)A fresh T from a full default plus this test's changesFixtures
createFixtureFactory<T>(defaults)Returns (overrides?) => T over one defaultsame
withOverrides(model, overrides?)A fixture from a model instance; its getters are read once, as datasame
narrow(value, predicate)The branch of a union the test expects, failing with the actual shape; also .byKey, .defined, .observable, .instanceOfsame
captureArg<T>(options?)Captures an argument the code under test built, to assert on it laterRecipes
createLog<T>()One call-order journal that several collaborators write toCall log

Modules and the event loop ​

ExportWhat it doesDocs
assertMocked(namespace, options?)Fails when the vi.mock() the spec relies on did not applyModule mocks
moduleNamespace(exports, options?)The object a vi.mock factory should return (default + __esModule)same
adoptMock(mock, options?)Turns a runner mock from a vi.mock factory into a typed function spysame
flushEventLoop(turns?)Runs real event-loop turns, even under fake timersEvent loop
flushEventLoopUntil(isDone, options?)Runs turns until a condition holds, with a budget instead of a hangsame
settleDynamicImport(load, turns?)Waits for an import() the code under test startedsame

Diagnostics in the core ​

ExportWhat it doesDocs
errorHandlerThe object whose throwArgumentsError builds the mustBeCalledWith failureControl helpers
describeDuplicateCopies() / getPackageCopies()Name the copies of this package loaded in one processSetup

Runner entry points ​

These re-export the whole core and register their runner's adapter instead of Vitest's.

ImportAddsDocs
vitest-auto-spy/buncreateNestUnit (from /nestjs)Bun
vitest-auto-spy/nodecreateNestUnit; trackNodeMocks(), pruneNodeMocks(), countNodeMocks() free spies node:test keepsnode:test
vitest-auto-spy/rstestnothingRstest
vitest-auto-spy/reactnothing; the same exports as vitest-auto-spy, under a React nameReact
vitest-auto-spy/sveltenothing; the same, under a Svelte nameSvelte
vitest-auto-spy/vueprovideAutoSpy for global.provide, plus Pinia store spiesVue

vitest-auto-spy/rxjs ​

Import it in each spec file that uses it, or once in the setup file. It turns on the Observable helpers and observablePropsToSpyOn, and makes returnSubject() an rxjs Subject<T> in the types.

ExportWhat it doesDocs
createObservableWithValues(configs, options?)Builds an Observable from a list of ValueConfigsrxjs

vitest-auto-spy/angular ​

Angular TestBed helpers on Vitest. You do not need import { … } from 'vitest-auto-spy' next to it; import 'vitest-auto-spy/rxjs' is still needed for nextWith. A typical spec imports import { injectSpy, provideAutoSpy, type Spy } from 'vitest-auto-spy/angular';.

ExportWhat it doesDocs
provideAutoSpy(Class, methodsOrConfig?)A TestBed provider that hands out a spy instead of the serviceReplace a service
injectSpy(token)Gets that spy from TestBed, typed Spy<T>same
provideAutoSpyForToken(token, overrides?, config?)The same for an InjectionToken, the spy built from the token's typeTokens
registerAutoSpyDefaults / clearAutoSpyDefaultsThe core's registration, also for an InjectionTokenDefaults
extendWithAutoSpies(test, spec, options?)Typed test fixtures for a map of dependencies (Vitest 4.1+)extendWithAutoSpies
createWithAutoSpies(Class, options?)Builds a class through DI with every unprovided dependency spiedAuto-spied dependencies
renderShallow(Component, options?)Renders a component without its child components (shallow render)Shallow rendering
prepareShallow(Component, options?)renderShallow with options shared by every test; .create(overrides?) per testprepareShallow
createComponentStub(Class, overrides?, options?)A standalone stand-in for a child component, directive or pipecreateComponentStub
createDirectiveHost(options)A standalone host component for a directive under testDirective host
setInputs(fixture, inputs, options?)Sets inputs by alias or field name, then waits until the fixture is stableChanging an input
hostElement(fixture, Type?) / queryElement(fixture, selector, Type?)The host element or a query match, typed and checked with instanceofTyped elements
stable(fixture, options?) / flushEffects()Waits for the component: flushes effects, then waits until the fixture is stable; with or without zone.jsZoneless waiting
settleResource(resource, options?)Waits until a resource() or httpResource() leaves loadingResources
mockResourceProp(object, property, initial, options?)Replaces a resource property with a ResourceRef double the spec drivesmockResourceProp
mockSignalProp(object, property, initial)Drives a signal property with a real writable signalDriving a signal
mockSignalProps(object, values)Sets several signals of a store double in one callsame
runEffect(effectRef)Runs one effect() body nowRunning one effect
trackRecomputations(signal) / trackEffectRuns(effectRef)Counts computed() recomputations or effect() runsCounting runs
overrideAutoSpy(Class, methodsOrConfig?)Replaces a provider everywhere in the TestBed, component providers includedOverrides
overrideComponentProvider(Component, Class, methodsOrConfig?)Replaces a provider the component declares for itselfsame
assertNgModuleScopes(...modules) / assertComponentDefIntact(...components)Checks that a module or component definition survived compilationsame
trackInjections(tokens, options?)Records which collaborators the code under test asked DI forTrack injections
setupAngularTestEnv(options)Runs zone and zoneless spec files in one workerZone and zoneless
Spy, the mock*Prop helpers, restoreMockedProps, countMockedProps, the expect*Emission* family, expectError, setEmissionTimeoutRe-exported from the coreCore

vitest-auto-spy/angular/matchers ​

Vitest only. Call each registrar once, from the setup file. Does not re-export the core.

ExportAdds the matcherDocs
registerSignalMatchers(options?)toHaveSignalValue(value); { strict: true } compares like toStrictEqualAsserting a signal
registerResourceMatchers()toBeLoading, toHaveResourceValue, toHaveResourceErrorAsserting a resource
registerDirectiveMatchers()toHaveDirectiveApplied(Directive, selector?) on a fixturetoHaveDirectiveApplied

vitest-auto-spy/angular/doubles ​

Ready-made doubles for Angular and Material services. Registers the Vitest adapter; does not re-export the core. @angular/material and @angular/cdk are never dependencies: you pass their classes in.

ExportWhat it doesDocs
provideWindowDouble(token, overrides?) / createWindowDouble(overrides?)A window with your overrides over the real one; create* works without TestBedWindow and document
provideDocumentDouble(overrides?, token?) / createDocumentDouble(overrides?)The same for documentsame
provideMatDialogData(token, data)The dialog's data for DI, typed by the tokenMaterial dialog
provideMatDialogRef(RefClass, init?) / injectMatDialogRef(RefClass, injector?) / createMatDialogRef(RefClass, init?)The dialog ref: spied close, emitClose(result?), afterClosed()same
providePlatform(platform, flags?)PLATFORM_ID and your own platform flags, in agreementPlatform and other doubles
provideDomSanitizerDouble() / createDomSanitizerDouble()A DomSanitizer whose bypass spies return real safe valuessame
provideChangeDetectorRefDouble() / createChangeDetectorRefDouble()A ChangeDetectorRef of four spiessame
provideOverlayDouble(Overlay, init?) / injectOverlayDouble(Overlay, injector?) / createOverlayDouble(Overlay, init?)A CDK Overlay whose refs you can drivesame

vitest-auto-spy/angular/diagnostics ​

Vitest only. Does not re-export the core and registers no adapter.

ExportWhat it doesDocs
enableAngularDiagnostics(options?) / disableAngularDiagnostics()Turns five silent TestBed mistakes into failing testsAngular diagnostics
assertNoPendingRequests(options?)Fails on HTTP requests nobody answeredassertNoPendingRequests
assertNoShadowedProviders(component, fixture)Fails when the component's own providers hide your spyassertNoShadowedProviders
enableTestBedDiagnostics(options?) / disableTestBedDiagnostics()Reports how much of each spec file's time went into TestBedWhere a spec spends its time
instrumentTestBed(), getTestBedTiming(), formatSpecTiming(timing), reportSpecTiming(timing)The building blocks of that report, for your own reportersame

vitest-auto-spy/angular-http ​

HttpClient and httpResource() in a spec. Needs @angular/common. Does not re-export the core.

ExportWhat it doesDocs
provideHttpTesting(options?)The HTTP client and its testing backend in one provider, with a teardown checkprovideHttpTesting
expectRequest(matcher, options?)Finds the one matching request and answers it, settling includedexpectRequest
expectNoRequest(matcher?, options?)Asserts that nothing matching was requestedexpectNoRequest
verifyNoPendingRequests(options?)Asserts that nothing was left unansweredverifyNoPendingRequests
injectHttpTesting()The HttpTestingController, for expectOne and friendsinjectHttpTesting

vitest-auto-spy/angular-router ​

Router doubles. Needs @angular/router. Does not re-export the core.

ExportWhat it doesDocs
provideActivatedRoute(init?)A real ActivatedRoute whose streams and snapshot come from one recordAngular router
injectActivatedRoute(injector?) / createActivatedRoute(init?)Its handle: setters move streams and snapshot togethersame
provideRouterDouble(init?)A Router over one URL; navigate and navigateByUrl are spiesThe router double
injectRouterDouble(injector?) / createRouterDouble(init?)Its handle: setUrl, emitNavigation, setCurrentNavigationsame
collectRouterEvents(events)Records router events as class and URL pairs, for one-line assertionscollectRouterEvents
provideLocationDouble() / injectLocationDouble(injector?) / createLocationDouble()Angular's SpyLocation and MockLocationStrategy in one callThe location double

vitest-auto-spy/signal-forms ​

Angular signal forms. Needs @angular/forms and Angular 22. Does not re-export the core.

ExportWhat it doesDocs
createForm(model, schema?, options?)Angular's form(), built in the TestBed injection contextSignal forms
registerFormMatchers()Adds toHaveFieldErrors(['required']): the field's whole error setsame

vitest-auto-spy/bun-angular ​

Angular's TestBed under bun test. Re-exports /bun (the whole core) and most of /angular: provideAutoSpy, injectSpy, renderShallow, prepareShallow, setInputs, hostElement, queryElement, createWithAutoSpies, stable, flushEffects, settleResource, runEffect, trackRecomputations, trackEffectRuns. Not included: the matchers, the diagnostics and the mock*Prop helpers. See Bun + Angular.

ExportWhat it does
registerDomGlobals(options?)Installs a DOM into a runtime that has none; returns the registrar used
createJsdomRegistrar(options) / createGlobalRegistratorRegistrar(options)The two DOM strategies it tries, for a custom preload
copyWindowGlobals(source, target)Copies a window's properties onto a global, keeping runtime built-ins
inlineAngularResources(source, path, options?)Rewrites templateUrl and styleUrl(s) into inline template and styles

vitest-auto-spy/nestjs ​

NestJS Test.createTestingModule helpers. Works on any runner: it uses the adapter your runner entry registered, and on Vitest builds one from vi. Does not re-export the core.

ExportWhat it doesDocs
provideAutoSpy(Class, methodsOrConfig?)A { provide, useValue } provider with a spyNestJS
injectSpy(moduleRef, token)Gets that spy from the testing module, typed Spy<T>same
createNestUnit(Class, options?)Builds a provider from its DI metadata with every dependency spiedBuilding the unit
trackInjections(tokens, options?)Records which collaborators the code asked DI forTrack injections

vitest-auto-spy/setup ​

One-call hygiene for a whole run, plus timers and network. Put setupAutoSpy() in the setup file.

ExportWhat it doesDocs
setupAutoSpy(options?)Turns on property restore, leak guards and a suite-wide strict in one callSetup
takeStrictViolations()Takes the strict-mode throws a test caused on purposeStrict mode
setupFakeTimers(config?, options?) / advanceTimers(ms?)Installs fake timers with a matching restore; advances and settles microtasksFake timers
withFakeTimers(fn, config?)Runs one body on fake timerssame
mockSystemTime(time) / withSystemTime(time, body) / mockNow(source) / useCountingClock(options?)Control what Date saysThe clock
restoreTimerGlobals() / getWatchedTimerGlobals()Puts back timer globals the fakes deleted / names the ones watchedSetup
blockNetwork(options?)Closes fetch, XHR and sendBeacon, naming what was requestedsame
stubResponse(init?)A real Response for a stubbed fetch, with no caststubResponse
BLOCKED_FETCH_MESSAGE / BLOCKED_XHR_MESSAGEThe fixed start of a refused request's message, to match onSetup
trackStrayTimers(host?, options?), countStrayTimers, cancelStrayTimers, describeStrayTimersFind and cancel timers that outlive their filesame
withoutStrayTimerTracking(work, host?)Runs setup work whose timers the tracker must ignoresame
flushUnhandledObservableErrors(host?) / expectUnhandledObservableErrors(expected?, host?)Surface Observable errors nothing handledsame
trackStrayRejections, countStrayRejections, flushStrayRejectionsRead back promise rejections zone.js swallowedsame
trackStrayListeners, baselineStrayListeners, countStrayListeners, describeStrayListeners, removeStrayListenersFind and remove window and document listeners a file leavessame
captureGlobalBaseline(host?) / restoreGlobals(host?)Snapshot globalThis once; put back every changed global at the file boundarysame
guardGlobalPatches(reaction)Names the test that made a global non-configurablesame
guardPrototypePollution(reaction)Names and removes a key left on Object.prototypesame
guardDocumentPollution(option)Names and removes an attribute left on <html>, <head> or <body>same
guardStrayConsole(option)Fails a test that wrote to the console without absorbing itsame
restoreWebStorage(options?) / restoreStorageSpies()A working localStorage / sessionStorage; removes spies mockRestore() cannotsame
installPerTest(install)Re-installs a stub before every test and returns the current handlesame
trackMockRegistry(), keepMockRegistered(mock), keepRegisteredMocks(), pruneMockRegistry(), getMockRegistrySize(), captureMockRegistry(), resetMockRegistryTracking()Keep Vitest's mock registry to the mocks that outlive a filesame
restoreLongLivedImplementations()Restores the implementation a cross-file vi.resetAllMocks() removedsame
setSpyEngine(engine) / getSpyEngine()Build method spies from the library's own mock ('auto-spy', default) or vi.fn() ('runner')The spy engine
registerFocusMatchers()Adds toHaveFocus(), which names why focus is elsewhereFocus assertions
isAngularUnitTestBuilder()Tells whether the run is under Angular's unit-test builderSetup
describeDuplicateCopies() / getPackageCopies()Re-exported from the coreCore

vitest-auto-spy/dom-stubs ​

Stand-ins for browser APIs the code under test creates itself. Registers the Vitest adapter only if no runner entry did. Stubs restore with restoreMockedProps().

ExportWhat it doesDocs
stubIntersectionObserver(options?), stubResizeObserver(options?), stubMutationObserver(options?), stubObserver(name, options?)Replace an observer global with one the spec drivesObserver stubs
intersectionEntry(target, isIntersecting, overrides?), resizeEntry(target, rect?), mutationRecord(target, init?)Build one observer entry without the unused fieldssame
stubMediaElement(options?)A <video> or <audio> that plays and fires media eventsMedia element
stubAnimationFrame(options?)requestAnimationFrame run at once or on flush(timestamp?)Frame and rect
stubElementRect(element, rect?)getBoundingClientRect() answering a real DOMRectsame
stubAbortController()An AbortController whose signal works with jsdom listenersConstructor doubles
stubWebStorage(key?, options?)An in-memory localStorage or sessionStorage with snapshot()Mocking localStorage
stubWorker(options?)A Worker whose script is the specWorker stub
createElementStub(options?)An HTMLElement for ElementRef whose spies keep stateElement stub
fillMissingDomApis(options?)Fills DOM members jsdom and happy-dom leave out, oncesame

vitest-auto-spy/diagnostics ​

Plain functions that register nothing; they also work from a Node script.

ExportWhat it doesDocs
explainSpy(spy, method?)Shows each configured argument list next to each recorded callexplainSpy
compareTestRuns(baseline, current, root?), summarizeTestRun(report, root?), formatTestRunComparison(comparison)Tell whether a migration lost a testDid the migration lose a test
diffByField(actual, expected)Which field of a list of records differs, and in how many elementsRecipes

vitest-auto-spy/console ​

Silent typed spies over the global console. See Console spies.

ExportWhat it does
consoleLogSpy, consoleInfoSpy, consoleWarnSpy, consoleErrorSpy, consoleDebugSpy, consoleTraceSpy, consoleTimeSpy, consoleTimeEndSpyThe spies, installed on import
useConsoleSpies()Installs the spies before each test of the block, restores after
installConsoleSpies() / resetConsoleSpies() / restoreConsole()Install, clear, undo
consoleOutput()Everything written, keyed by channel
consoleLines()Everything written, as one list in call order

Other entry points ​

ImportExportsDocs
vitest-auto-spy/jasminecreateSpyObj, the jasmine namespace, registerJasmineMatchers, enableJasmineCompat, plus createSpyFromClass, createFunctionSpy, provideAutoSpy with .and / .calls; Vitest onlyMigrating from Jasmine
vitest-auto-spy/jasmine-compatenableJasmineCompat() alone, for bun test and node --testOn Bun and node:test
vitest-auto-spy/observer-spysubscribeSpyTo, ObserverSpy, SubscriberSpy: the @hirez_io/observer-spy APIrxjs
vitest-auto-spy/zoneinstallProxyZonePatch(options?), installed on import: fakeAsync under VitestZone
vitest-auto-spy/eslint-pluginThe flat-config lint plugin (default export)ESLint plugin
vitest-auto-spy/perf-reporterThe Vitest reporter npx vitest-auto-spy perf uses (default export)CLI
vitest-auto-spy/package.jsonThe manifest, for tools that read it (Storybook, Nx)—

Configuration objects ​

The second argument of createSpyFromClass, createSpyFromInstance and provideAutoSpy is a ClassSpyConfiguration. All options with examples: Spies from a class.

OptionTypeWhat it does
methodsToSpyOnstring[]Adds callables to the methods found on the prototype
onlyMethodsToSpyOnstring[]Spies only these; nothing is discovered
instanceMethodsToSpyOnstring[]Like methodsToSpyOn, for callables on the instance (signal() fields, arrow props)
observablePropsToSpyOnstring[]Observable properties that get nextWith and friends
gettersToSpyOn / settersToSpyOnstring[]Accessors to spy on, read back through accessorSpies
autoSpyAccessorsbooleanFinds getters and setters by itself
returns{ method: value }What a method returns from the start (for an Observable method, pass of(value)); the method stays a spy
returnsUndefinedstring[]Methods that answer undefined; counts as configured under strict
returnsClass{ method: Class }The method answers one spy of that class per double, reached as innerDouble(double, 'method'); [Class, options] configures it, { build } answers what a preset builds — details
overrides{ member: value }Replaces a member with a plain value (see returns or overrides)
selfReturningstring[]Methods that return the double itself, for chained calls
fillMissingbooleanAdds a spy for a name the prototype does not have (abstract members)
lazySpiesboolean | 'proxy'When method spies are built ('proxy': one proxy object builds them on first use); unset, the number of methods decides
strict, onUnstubbedCall, onUnstubbedReadsee belowStrict mode
passthroughbooleancreateSpyFromInstance only: unconfigured methods run the real one

createAutoMock, autoMocked and provideAutoSpyForToken take an AutoMockConfiguration as the last argument: observablePropsToSpyOn, returns, returnsUndefined, returnsClass, selfReturning, name (what a strict report calls the double), and the strict fields. With nothing to seed, the options can go first: createAutoMock<EventSource>({ returnsUndefined: ['close'] }). That works when the object names at least one of returnsUndefined, selfReturning, returnsClass, observablePropsToSpyOn, onUnstubbedCall, onUnstubbedRead; strict, name or returns alone still go second — options without values.

StrictSpyConfiguration: accepted by every factory, and by setupAutoSpy(options?) as a suite-wide default. See precedence.

FieldTypeWhat it does
strict?booleanA call to a method nobody configured throws, naming class, method and arguments. Default off
onUnstubbedCall?(call: { className: string | undefined; method: string; args: unknown[] }) => unknownRuns instead, and its result becomes the call's result. Wins over strict
onUnstubbedRead?(read: { className: string | undefined; member: string; kind: 'getter' | 'observable'; count: number }) => voidGets the getters read and streams subscribed with nothing configured, after the test. Needs setupAutoSpy

ValueConfig (for nextWithValues, createObservableWithValues): { value, delay? }, { errorValue, delay? } or { complete?, delay? }.

createSpyClass options: { statics?: boolean } copies the class's static members onto the double. See statics.

captureArg options: { where? }, a predicate choosing which values the captor accepts.

Public types ​

The core exports these; most of them you only see in an error message.

TypeWhat it isDocs
Spy<T>The spy object: each method of T plus the helpers its return type allows, plus accessorSpiesSpy typing
Spy<T, Options>{ overload?: 'first' | 'last' } picks the overload the helpers readOverloads
FunctionSpy<Fn>What createFunctionSpy returnsOne function
DeepMockProxy<T>What mockDeep returnsmockDeep
AutoMocked<T>What autoMocked returns: T and Spy<T> at onceautoMocked
DeepPartial<T>What createMock and createAutoMock take: partial at every depthFixtures
ClassType<T>A class of T, abstract classes includedSpies from a class
SpyDisposableMakes every double work with usingusing
ObservableLike<T>, SubjectLike<T>, SubjectOf<T>, AutoSpyRxjsTypes<T>How the types recognise a stream without naming rxjsrxjs in the types
SubscribableLike<T>, CallbackSubscribable<T>, EmissionSource<T>What the Observable assertions acceptWhich sources work
AddSpyMethodsByReturnTypes<Method>The helpers one method getsSpy typing

Every exported type, by entry point. The list is for lookup; the table above covers the ones you use.

text
vitest-auto-spy (also re-exported by /bun, /node, /rstest, /react, /svelte, /vue, /bun-angular)
  AccessorImplementations, AccessorKeysOf, AddAccessorsSpies, AddCalledWithAny,
  AddCalledWithObservable, AddCalledWithPromise, AddCalledWithSpyMethods, AddObservableSpyMethods,
  AddPromiseSpyMethods, AddSpyMethodsByReturnTypes, AddThrowHelper, AddVoidReturnHelpers,
  AdoptMockOptions, AdoptedMock, AnyReturnHelpers, ArgCaptor, AsInstances, AssertMockedOptions,
  AutoMockConfiguration, AutoMocked, AutoSpyDefaultEntry, AutoSpyRxjsTypes, CallLog,
  CallbackSubscribable, CaptureArgOptions, ClassSpyConfiguration, ClassType, CompleteValueConfig,
  ConstructorMock, ConstructorSpy, DeepMockProxy, DeepPartial, EmissionObserver, EmissionOptions,
  EmissionSource, ErrorValueConfig, FixtureFactory, FlushUntilOptions, Func, FunctionSpy,
  InstanceSpyConfiguration, MethodReturns, MockDeepOptions, ModuleNamespace,
  ModuleNamespaceOptions, Mutable, NextValueConfig, NotAPublicKey, ObservableLike,
  ObservablePropSpyMethods, OnlyMethodKeysOf, OnlyObservablePropsOf, OnlyPropsOf,
  OutsideHookReaction, Overload, OverloadChoice, Overloads, PropStubValue, RestoreProp, Spy,
  SpyClassOptions, SpyDisposable, SpyOptions, StrictSpyConfiguration, SubjectLike, SubjectOf,
  SubscribableLike, UnstubbedCall, UnstubbedCallHandler, UnstubbedRead, UnstubbedReadHandler,
  ValueConfig, ValueConfigPerCall, WithMockReturnValue

/rxjs (re-exported from the core)
  AddObservableSpyMethods, CompleteValueConfig, ErrorValueConfig, NextValueConfig,
  ObservablePropSpyMethods, ValueConfig, ValueConfigPerCall

/angular
  AccessorImplementations, AngularTestEnvMode, AngularTestEnvOptions, AngularTokenProvider,
  AngularValueProvider, AutoSpiedInstance, AutoSpyFixture, AutoSpyOverride, AutoSpyTokenDefaults,
  CallbackSubscribable, ComponentInputs, ComponentStubOptions, CreateWithAutoSpiesOptions,
  DirectiveHostOptions, ElementConstructor, EmissionObserver, EmissionOptions, EmissionSource,
  ExtendWithAutoSpiesOptions, InjectionLog, MockResourceOptions, MockedResource,
  NativeElementHolder, PreparedShallow, RenderShallowOptions, ResourceDouble,
  ResourceDoubleSnapshot, ResourceDoubleStatus, ResourceStatusLike, RestoreProp, RunCounter,
  SettleResourceOptions, ShallowOverrides, ShallowRender, SignalPropHandles, SignalPropValues,
  SpiedFixtures, Spy, SpyRegistry, StableOptions, SubjectOf, SubscribableLike,
  TrackInjectionsOptions, TrackedProvider

/angular/diagnostics
  AngularDiagnosticsOptions, PendingRequestsOptions, SpecTiming, TestBedDiagnosticsOptions

/angular/doubles
  AttachedComponent, DialogComponent, DialogDataOf, DialogRefLike, DialogResult,
  MatDialogRefDouble, MatDialogRefInit, OverlayDouble, OverlayDoubleInit, OverlayLike,
  OverlayRefDouble, OverlayRefStub, PlatformFlagTokens, PlatformName, PlatformOverrides,
  PositionCall

/angular/matchers
  RegisterSignalMatchersOptions, ResourceLike, SignalLike, SignalValueOptions

/angular-http
  ExpectRequestOptions, FlushOptions, HttpTestingOptions, RequestErrorOptions, RequestExpectation,
  RequestMatcher, ResponseBody

/angular-router
  ActivatedRouteChange, ActivatedRouteDouble, ActivatedRouteInit, LocationDouble, NavigationInit,
  RouteResources, RouterDouble, RouterDoubleInit, RouterEventPair, RouterEventsHandle

/signal-forms
  CreateFormOptions, FieldErrorMatch

/bun-angular (beyond the core)
  AngularResourceInlinerOptions, AngularValueProvider, AutoSpiedInstance, ComponentInputs,
  CreateNestUnitOptions, CreateWithAutoSpiesOptions, DomRegistrar, ElementConstructor,
  GlobalRegistratorOptions, JsdomModule, JsdomRegistrarOptions, NativeElementHolder, NestUnit,
  NestUnitClass, NestUnitProvider, NestUnitSpies, PreparedShallow, RegisterDomGlobalsOptions,
  RenderShallowOptions, ResourceStatusLike, RunCounter, SettleResourceOptions, ShallowOverrides,
  ShallowRender, SpyRegistry, StableOptions

/nestjs
  CreateNestUnitOptions, InjectionLog, NestModuleRef, NestUnit, NestUnitClass, NestUnitProvider,
  NestUnitSpies, NestValueProvider, TrackInjectionsOptions, TrackedProvider

/bun (beyond the core)
  CreateNestUnitOptions, NestUnit, NestUnitClass, NestUnitProvider, NestUnitSpies

/node (beyond the core)
  CreateNestUnitOptions, NestUnit, NestUnitClass, NestUnitProvider, NestUnitSpies,
  StopTrackingNodeMocks

/vue (beyond the core)
  VueInjectionToken, VueProvideSpy

/setup
  BlockNetworkOptions, CountingClock, CountingClockOptions, DocumentPollutionOptions,
  DocumentPollutionReaction, DuplicateCopiesReaction, ExpectedUnhandledError, FakeTimersConfig,
  GlobalPatchReaction, MisconfigurationReaction, PerTestHandle, PrototypePollutionReaction,
  RejectionHost, RestoreWebStorageOptions, SchedulerHost, SetupAutoSpyOptions, SetupAutoSpyPreset,
  SpyEngine, StopTrackingListeners, StopTrackingRejections, StopTrackingTimers, StorageSpyKey,
  StrayConsoleOptions, StrayConsoleReaction, StrayListener, StrayListenerReport, StrayRejection,
  StrayTimer, StrayTimerReport, StrayTimersOptions, StubResponseInit, SwallowedStrictCallsReaction,
  SystemTime, TrackedListenerTarget, UnconfiguredReadsReaction, UnhandledObservableError,
  XhrBlockMode

/dom-stubs
  AnimationFrameMode, AnimationFrameStub, AnimationFrameStubOptions, CancelAnimationFrameFn,
  ClassListStub, ElementRectRestore, ElementStub, ElementStubOptions, FillMissingDomApisOptions,
  IntersectionEntryOverrides, IntersectionObserverStubOptions, MediaElementState, MediaElementStub,
  MediaElementStubOptions, MutationRecordInit, ObserverGlobal, ObserverInstance, ObserverStub,
  ObserverStubOptions, RequestAnimationFrameFn, ResizeEntryRect, StyleStub, WebStorageKey,
  WebStorageStub, WebStorageStubOptions, WorkerInstance, WorkerScript, WorkerStub,
  WorkerStubOptions

/diagnostics
  TestRunComparison, TestRunReport, TestRunSummary

/console
  ConsoleChannel, ConsoleLine, ConsoleMethodSpy, ConsoleOutput, ConsoleSpies

/jasmine
  AngularValueProvider, ClassSpyConfiguration, ClassType, JasmineAccessorSpies, JasmineAccessorSpy,
  JasmineAnd, JasmineCallInfo, JasmineCalls, JasmineClassSpyConfiguration, JasmineClock,
  JasmineMethodSpy, JasmineNamespaces, JasmineSpy, JasmineStrategies, JasmineWithArgsAnd,
  JasmineWithArgsStrategies, JasmineWithArgsSync, OnlyMethodKeysOf, OnlyObservablePropsOf,
  OnlyPropsOf, Spy, SpyObj

/jasmine-compat
  JasmineAccessorSpies, JasmineAccessorSpy, JasmineAnd, JasmineCallInfo, JasmineCalls,
  JasmineMethodSpy, JasmineNamespaces, JasmineSpy, JasmineStrategies, JasmineWithArgsAnd,
  JasmineWithArgsStrategies, JasmineWithArgsSync

/observer-spy
  ObserverSpyConfig, ObserverSpyWaitOptions

/zone
  ProxyZonePatchOptions, ProxyZoneScope

/eslint-plugin
  AutoSpyEslintPlugin, FlatConfig, PluginRule, RuleSeverity

In depth ​

Details that have no other page yet.

  • Where the DOM stubs went. The /dom-stubs helpers and the /diagnostics functions moved out of the core in 4.0; see Upgrading to 4.0.
  • createSpyFromInstance configuration. It takes ClassSpyConfiguration but ignores lazySpies and fillMissing: the members already exist, and an instance has no erased abstract members. It reports the same misconfigurations as the class factory, judged against the live object, so an arrow-function field counts as a member.
  • Suite-wide strict. setupAutoSpy arms the default only when you pass strict or onUnstubbedCall, and releases it in afterAll. Without that, under isolate: false a default armed by one file would stay armed for files that never asked for it. The default lives on globalThis, so it reaches a double whichever bundle of the package built it. An explicit strict: false on a double is the only way to exempt one wide collaborator.
  • className in the strict hooks is the class the double was built from, or the name a type-driven double was given, or createAutoMock(file:line) when it has none.
  • SpyDisposable is { [Symbol.dispose](): void }, declared structurally rather than as the global Disposable. That global lives in lib.esnext.disposable, so a project whose lib stops at ES2022 and has no @types/node would fail on the published types. Spy<T> stays assignable to Disposable wherever it exists. Disposing any node of a mockDeep tree resets the whole tree.
  • SubscribableLike<T> / CallbackSubscribable<T> are the two subscription shapes the Observable assertions accept: an observer object, as rxjs takes, and a bare next callback, as Angular's output() takes. EmissionSource<T> is their union.
  • AddCalledWithAny<Method> / AnyReturnHelpers. A method whose return type is any keeps mockReturnValue on its calledWith chain and gets the Promise and Observable helpers too, because at run time it has all of them. These two types name that chain and that bundle, for a signature built outside Spy<T>.
  • DeepPartial<T> still rejects a key T does not have, at every depth. Date, Map, Promise and functions pass through untouched, and a real value is accepted wherever a partial is, so a host object such as a NodeList stays assignable.
  • SubjectOf from /angular does not augment anything: a variable typed with it is rxjs's Subject only where vitest-auto-spy/rxjs is in the TypeScript program, and SubjectLike otherwise.
  • restoreGlobals() and DOM globals. Vitest puts the jsdom or happy-dom window's properties on globalThis as getter and setter pairs that forward to the window. global.ResizeObserver = stub runs the setter and leaves the property descriptor unchanged. So restoreGlobals() writes the old value back through the same setter, not only by comparing descriptors.
  • mockResourceProp after fail(): value() throws a ResourceValueError, like a real failed resource.

Released under the MIT License.