Skip to content
Vitest 1
Main Navigation LeitfadenAPIKonfigurationFortgeschritten
1.6.1
0.34.6

Deutsch

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

Deutsch

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

Aussehen

Sidebar Navigation

Leitfaden

Warum Vitest

Erste Schritte

Features

Arbeitsbereich

Kommandozeilenschnittstelle

Testfilter

Reporter

Codeabdeckung (Coverage)

Snapshot

Mocking

Typen testen

Vitest UI

Browser-Modus

In-Source-Testing

Testkontext

Testumgebung

Erweiterung von Matchern

IDE-Integration

Debugging

Vergleiche mit anderen Test-Runnern

Migrationsleitfaden

Häufige Fehler

Leistungsverbesserung

API

Test API Referenz

Mock-Funktionen

Vi

expect

expectTypeOf

assert

assertType

Konfiguration

Verwaltung der Vitest-Konfigurationsdatei

Vitest konfigurieren

Auf dieser Seite

Vi ​

Vitest stellt Hilfsfunktionen über seine vi-Funktion bereit. Du kannst global darauf zugreifen (wenn die Globals-Konfiguration aktiviert ist) oder sie direkt von vitest importieren:

js
import { vi } from 'vitest';

Module mocken ​

Dieser Abschnitt beschreibt die API, die du verwenden kannst, wenn du ein Modul mocken möchtest. Beachte, dass Vitest das Mocken von Modulen, die mit require() importiert wurden, nicht unterstützt.

vi.mock ​

  • Typ: (path: string, factory?: (importOriginal: () => unknown) => unknown) => void

Ersetzt alle Importe des Moduls unter dem angegebenen path durch ein anderes Modul. Du kannst konfigurierte Vite-Aliase innerhalb eines Pfades verwenden. Der Aufruf von vi.mock wird hochgezogen (hoisted), daher ist es unerheblich, wo du ihn aufrufst. Er wird immer vor allen Importen ausgeführt. Wenn du auf Variablen außerhalb seines Gültigkeitsbereichs verweisen musst, kannst du diese innerhalb von vi.hoisted definieren und innerhalb von vi.mock darauf verweisen.

WARNING

vi.mock funktioniert nur für Module, die mit dem Schlüsselwort import importiert wurden. Es funktioniert nicht mit require.

Um vi.mock zu hoisten, analysiert Vitest deine Dateien statisch. Dies bedeutet, dass vi, das nicht direkt aus dem vitest-Paket importiert wurde (z.B. aus einer Utility-Datei), nicht funktioniert. Verwende vi.mock mit vi, das von vitest importiert wurde, oder aktiviere die Konfigurationsoption globals.

Vitest wird keine Module mocken, die innerhalb einer Setup-Datei importiert wurden, da diese zwischengespeichert werden, wenn eine Testdatei ausgeführt wird. Du kannst vi.resetModules() innerhalb von vi.hoisted aufrufen, um alle Modul-Caches zu löschen, bevor eine Testdatei ausgeführt wird.

WARNING

Der Browser-Modus unterstützt derzeit keine Mock-Module. Du kannst diese Funktion im GitHub Issue verfolgen.

Wenn factory definiert ist, geben alle Importe dessen Ergebnis zurück. Vitest ruft die Factory nur einmal auf und speichert die Ergebnisse für alle nachfolgenden Importe zwischen, bis vi.unmock oder vi.doUnmock aufgerufen wird.

Anders als in jest kann die Factory asynchron sein. Du kannst vi.importActual oder eine Hilfsfunktion mit der als erstes Argument übergebenen Factory verwenden und das ursprüngliche Modul darin erhalten.

js
import { vi } from 'vitest';
// ---cut---
// bei Verwendung von JavaScript

vi.mock('./path/to/module.js', async importOriginal => {
  const mod = await importOriginal();
  return {
    ...mod,
    // einige Exporte ersetzen
    namedExport: vi.fn(),
  };
});
ts
// bei Verwendung von TypeScript

vi.mock('./path/to/module.js', async importOriginal => {
  const mod = await importOriginal<typeof import('./path/to/module.js')>();
  return {
    ...mod,
    // einige Exporte ersetzen
    namedExport: vi.fn(),
  };
});

WARNING

vi.mock wird an den Anfang der Datei hochgezogen (anders ausgedrückt, verschoben). Das bedeutet, dass es, egal wo du es schreibst (sei es innerhalb von beforeEach oder test), tatsächlich vorher aufgerufen wird.

Dies bedeutet auch, dass innerhalb der Factory keine Variablen verwendet werden können, die außerhalb der Factory definiert sind.

Wenn du Variablen innerhalb der Factory verwenden musst, versuche vi.doMock. Es funktioniert auf die gleiche Weise, wird aber nicht hochgezogen. Beachte, dass es nur nachfolgende Importe mockt.

Du kannst auch auf Variablen verweisen, die von der vi.hoisted-Methode definiert wurden, wenn sie vor vi.mock deklariert wurde:

ts
import { namedExport } from './path/to/module.js';

const mocks = vi.hoisted(() => {
  return {
    namedExport: vi.fn(),
  };
});

vi.mock('./path/to/module.js', () => {
  return {
    namedExport: mocks.namedExport,
  };
});

vi.mocked(namedExport).mockReturnValue(100);

expect(namedExport()).toBe(100);
expect(namedExport).toBe(mocks.namedExport);

WARNING

Wenn du ein Modul mit einem Standardexport mocken möchtest, musst du einen default-Schlüssel innerhalb des zurückgegebenen Factory-Funktionsobjekts angeben. Dies ist eine Besonderheit von ES-Modulen; die jest-Dokumentation kann sich daher unterscheiden, da jest CommonJS-Module verwendet. Zum Beispiel:

ts
vi.mock('./path/to/module.js', () => {
  return {
    default: { myDefaultKey: vi.fn() },
    namedExport: vi.fn(),
    // etc...
  };
});

Wenn es einen __mocks__-Ordner neben einer Datei gibt, die du mocken möchtest, und die Factory nicht bereitgestellt wird, versucht Vitest, eine Datei mit demselben Namen im __mocks__-Unterordner zu finden und sie als tatsächliches Modul zu verwenden. Wenn du eine Abhängigkeit mocken möchtest, versucht Vitest, einen __mocks__-Ordner im Root des Projekts zu finden (Standard ist process.cwd()). Du kannst Vitest mitteilen, wo sich die Abhängigkeiten befinden, über die Konfigurationsoption deps.moduleDirectories.

Zum Beispiel hast du diese Dateistruktur:

- __mocks__
  - axios.js
- src
  __mocks__
    - increment.js
  - increment.js
- tests
  - increment.test.js

Wenn du vi.mock in einer Testdatei aufrufst, ohne eine Factory bereitzustellen, wird eine Datei im __mocks__-Ordner gesucht, die als Modul verwendet werden soll:

ts
// increment.test.js
import { vi } from 'vitest';

// axios ist ein Standardexport von `__mocks__/axios.js`
import axios from 'axios';

// increment ist ein benannter Export von `src/__mocks__/increment.js`
import { increment } from '../increment.js';

vi.mock('axios');
vi.mock('../increment.js');

axios.get(`/apples/${increment(1)}`);

WARNING

Beachte, dass Module nicht automatisch gemockt werden, wenn du vi.mock nicht aufrufst. Um das Automocking-Verhalten von Jest zu replizieren, kannst du vi.mock für jedes erforderliche Modul innerhalb von setupFiles aufrufen.

Wenn kein __mocks__-Ordner vorhanden ist oder keine Factory bereitgestellt wird, importiert Vitest das ursprüngliche Modul und mockt automatisch alle seine Exporte. Für die angewendeten Regeln siehe Verfahren.

vi.doMock ​

  • Typ: (path: string, factory?: (importOriginal: () => unknown) => unknown) => void

Das gleiche wie vi.mock, aber es wird nicht an den Anfang der Datei hochgezogen, sodass du auf Variablen im globalen Dateibereich verweisen kannst. Der nächste dynamische Import des Moduls wird gemockt.

WARNING

Dies mockt keine Module, die importiert wurden, bevor dies aufgerufen wurde. Vergiss nicht, dass alle statischen Importe in ESM immer hochgezogen werden, sodass das Platzieren vor einem statischen Import nicht erzwingt, dass er vor dem Import aufgerufen wird:

ts
vi.doMock('./increment.js'); // dies wird _erst nach_ der Importanweisung aufgerufen

import { increment } from './increment.js';
ts
// ./increment.js
export function increment(number) {
  return number + 1;
}
ts
import { beforeEach, test } from 'vitest';
import { increment } from './increment.js';

// das Modul wird nicht gemockt, da vi.doMock noch nicht aufgerufen wurde
increment(1) === 2;

let mockedIncrement = 100;

beforeEach(() => {
  // Sie können auf Variablen innerhalb einer Factory zugreifen
  vi.doMock('./increment.js', () => ({ increment: () => ++mockedIncrement }));
});

test('importing the next module imports mocked one', async () => {
  // der ursprüngliche Import wurde NICHT gemockt, da `vi.doMock` erst NACH den Importen ausgewertet wird
  expect(increment(1)).toBe(2);
  const { increment: mockedIncrement } = await import('./increment.js');
  // neuer dynamischer Import gibt gemocktes Modul zurück
  expect(mockedIncrement(1)).toBe(101);
  expect(mockedIncrement(1)).toBe(102);
  expect(mockedIncrement(1)).toBe(103);
});

vi.mocked ​

  • Typ: <T>(obj: T, deep?: boolean) => MaybeMockedDeep<T>
  • Typ: <T>(obj: T, options?: { partial?: boolean; deep?: boolean }) => MaybePartiallyMockedDeep<T>

TypeScript-Hilfe für Typen. Gibt nur das übergebene Objekt zurück.

Wenn partial true ist, wird ein Partial<T> als Rückgabewert erwartet. Standardmäßig lässt dies TypeScript nur glauben, dass die Werte der ersten Ebene gemockt sind. Du kannst { deep: true } als zweites Argument übergeben, um TypeScript mitzuteilen, dass das gesamte Objekt gemockt ist, wenn dies tatsächlich der Fall ist.

ts
import example from './example.js';

vi.mock('./example.js');

test('1 + 1 equals 10', async () => {
  vi.mocked(example.calc).mockReturnValue(10);
  expect(example.calc(1, '+', 1)).toBe(10);
});

vi.importActual ​

  • Typ: <T>(path: string) => Promise<T>

Importiert ein Modul und umgeht alle Prüfungen, ob es gemockt werden soll. Kann nützlich sein, wenn du ein Modul teilweise mocken möchtest.

ts
vi.mock('./example.js', async () => {
  const axios = await vi.importActual('./example.js');

  return { ...axios, get: vi.fn() };
});

vi.importMock ​

  • Typ: <T>(path: string) => Promise<MaybeMockedDeep<T>>

Importiert ein Modul, wobei alle seine Eigenschaften (einschließlich verschachtelter Eigenschaften) gemockt werden. Befolgt die gleichen Regeln wie vi.mock. Für die angewendeten Regeln siehe Verfahren.

vi.unmock ​

  • Typ: (path: string) => void

Entfernt ein Modul aus der Mock-Registry. Alle Aufrufe von import geben das ursprüngliche Modul zurück, auch wenn es zuvor gemockt wurde. Dieser Aufruf wird an den Anfang der Datei gehoistet, sodass nur Module unmocked werden, die beispielsweise in setupFiles definiert wurden.

vi.doUnmock ​

  • Typ: (path: string) => void

Das gleiche wie vi.unmock, wird aber nicht an den Anfang der Datei hochgezogen. Der nächste Import des Moduls importiert das ursprüngliche Modul anstelle des Mocks. Dies unmocked keine zuvor importierten Module.

ts
// ./increment.js
export function increment(number) {
  return number + 1;
}
ts
import { increment } from './increment.js';

// increment ist bereits gemockt, da vi.mock gehoistet wird
increment(1) === 100;

// dies wird gehoistet, und die Factory wird vor dem Import in Zeile 1 aufgerufen
vi.mock('./increment.js', () => ({ increment: () => 100 }));

// alle Aufrufe werden gemockt, und `increment` gibt immer 100 zurück
increment(1) === 100;
increment(30) === 100;

// dies wird nicht gehoistet, sodass ein anderer Import ein "unmocked" Modul zurückgibt
vi.doUnmock('./increment.js');

// dies gibt IMMER NOCH 100 zurück, weil `vi.doUnmock` ein Modul nicht neu bewertet
increment(1) === 100;
increment(30) === 100;

// der nächste Import ist unmocked, jetzt ist `increment` die ursprüngliche Funktion, die count + 1 zurückgibt
const { increment: unmockedIncrement } = await import('./increment.js');

unmockedIncrement(1) === 2;
unmockedIncrement(30) === 31;

vi.resetModules ​

  • Typ: () => Vitest

Setzt die Modul-Registry zurück, indem der Cache aller Module geleert wird. Dies ermöglicht es, Module neu zu bewerten, wenn sie erneut importiert werden. Top-Level-Importe können nicht neu bewertet werden. Kann nützlich sein, um Module zu isolieren, bei denen lokale Zustände zwischen Tests in Konflikt stehen.

ts
import { vi } from 'vitest';

import { data } from './data.js'; // Wird nicht vor jedem Test erneut ausgewertet

beforeEach(() => {
  vi.resetModules();
});

test('change state', async () => {
  const mod = await import('./some/path.js'); // Wird neu bewertet
  mod.changeLocalState('new value');
  expect(mod.getLocalState()).toBe('new value');
});

test('module has old state', async () => {
  const mod = await import('./some/path.js'); // Wird neu bewertet
  expect(mod.getLocalState()).toBe('old value');
});

WARNING

Setzt die Mock-Registry nicht zurück. Um die Mock-Registry zu leeren, verwende vi.unmock oder vi.doUnmock.

vi.dynamicImportSettled ​

Wartet, bis alle dynamischen Importe abgeschlossen sind. Nützlich, wenn du einen synchronen Aufruf hast, der einen dynamischen Import startet, auf den du sonst nicht warten kannst.

ts
import { expect, test } from 'vitest';

// kann Import nicht verfolgen, da Promise nicht zurückgegeben wird
function renderComponent() {
  import('./component.js').then(({ render }) => {
    render();
  });
}

test('operations are resolved', async () => {
  renderComponent();
  await vi.dynamicImportSettled();
  expect(document.querySelector('.component')).not.toBeNull();
});

TIP

Wenn während eines dynamischen Imports ein weiterer dynamischer Import initiiert wird, wartet diese Methode, bis alle aufgelöst sind.

Diese Methode wartet auch auf den nächsten setTimeout-Tick, nachdem der Import aufgelöst wurde, sodass alle synchronen Operationen abgeschlossen sein sollten, wenn er aufgelöst wird.

Mocken von Funktionen und Objekten ​

Dieser Abschnitt beschreibt, wie man mit Methoden-Mocks arbeitet und Umgebungs- und globale Variablen ersetzt.

vi.fn ​

  • Typ: (fn?: Function) => Mock

Erstellt einen Spion für eine Funktion, kann aber auch ohne eine solche initialisiert werden. Jedes Mal, wenn eine Funktion aufgerufen wird, speichert sie ihre Aufrufargumente, Rückgabewerte und Instanzen. Außerdem kannst du ihr Verhalten mit Methoden manipulieren. Wenn keine Funktion angegeben wird, gibt Mock undefined zurück, wenn er aufgerufen wird.

ts
import { expect, vi } from 'vitest';
// ---cut---
const getApples = vi.fn(() => 0);

getApples();

expect(getApples).toHaveBeenCalled();
expect(getApples).toHaveReturnedWith(0);

getApples.mockReturnValueOnce(5);

const res = getApples();
expect(res).toBe(5);
expect(getApples).toHaveNthReturnedWith(2, 5);

vi.isMockFunction ​

  • Typ: (fn: Function) => boolean

Prüft, ob ein gegebener Parameter eine Mock-Funktion ist. Wenn du TypeScript verwendest, wird auch sein Typ eingeschränkt.

vi.clearAllMocks ​

Ruft .mockClear() auf allen Spionen auf. Dadurch wird der Mock-Verlauf geleert, aber die Implementierung nicht auf die Standardeinstellung zurückgesetzt.

vi.resetAllMocks ​

Ruft .mockReset() auf allen Spionen auf. Dadurch wird der Mock-Verlauf geleert und die Implementierung auf eine leere Funktion zurückgesetzt (gibt undefined zurück).

vi.restoreAllMocks ​

Ruft .mockRestore() auf allen Spionen auf. Dadurch wird der Mock-Verlauf geleert und die Implementierung auf die ursprüngliche zurückgesetzt.

vi.spyOn ​

  • Typ: <T, K extends keyof T>(object: T, method: K, accessType?: 'get' | 'set') => MockInstance

Erstellt einen Spion für eine Methode oder einen Getter/Setter eines Objekts, ähnlich wie vi.fn(). Es gibt eine Mock-Funktion zurück.

ts
import { expect, vi } from 'vitest';
// ---cut---
let apples = 0;
const cart = {
  getApples: () => 42,
};

const spy = vi.spyOn(cart, 'getApples').mockImplementation(() => apples);
apples = 1;

expect(cart.getApples()).toBe(1);

expect(spy).toHaveBeenCalled();
expect(spy).toHaveReturnedWith(1);

TIP

Du kannst vi.restoreAllMocks innerhalb von afterEach aufrufen (oder test.restoreMocks aktivieren), um alle Methoden auf ihre ursprünglichen Implementierungen zurückzusetzen. Dadurch wird die ursprüngliche Objektbeschreibung wiederhergestellt, sodass du die Implementierung der Methode nicht ändern kannst:

ts
const cart = {
  getApples: () => 42,
};

const spy = vi.spyOn(cart, 'getApples').mockReturnValue(10);

console.log(cart.getApples()); // 10
vi.restoreAllMocks();
console.log(cart.getApples()); // 42
spy.mockReturnValue(10);
console.log(cart.getApples()); // still 42!

vi.stubEnv 0.26.0+ ​

  • Typ: (name: string, value: string) => Vitest

Ändert den Wert der Umgebungsvariable in process.env und import.meta.env. Du kannst ihren Wert wiederherstellen, indem du vi.unstubAllEnvs aufrufst.

ts
import { vi } from 'vitest';

// `process.env.NODE_ENV` und `import.meta.env.NODE_ENV`
// `process.env.NODE_ENV` und `import.meta.env.NODE_ENV` haben den Wert "development", bevor `vi.stubEnv` aufgerufen wird

vi.stubEnv('NODE_ENV', 'production');

process.env.NODE_ENV === 'production';
import.meta.env.NODE_ENV === 'production';
// ändert keine anderen Umgebungsvariable
import.meta.env.MODE === 'development';

TIP

Du kannst den Wert auch ändern, indem du ihn einfach zuweist, aber du kannst vi.unstubAllEnvs nicht verwenden, um den vorherigen Wert wiederherzustellen:

ts
import.meta.env.MODE = 'test';

vi.unstubAllEnvs 0.26.0+ ​

  • Typ: () => Vitest

Stellt alle import.meta.env- und process.env-Werte wieder her, die mit vi.stubEnv geändert wurden. Wenn es zum ersten Mal aufgerufen wird, merkt sich Vitest den ursprünglichen Wert und speichert ihn, bis unstubAllEnvs erneut aufgerufen wird.

ts
import { vi } from 'vitest';

// `process.env.NODE_ENV` und `import.meta.env.NODE_ENV`
// `process.env.NODE_ENV` und `import.meta.env.NODE_ENV` haben den Wert "development", bevor `stubEnv` aufgerufen wird

vi.stubEnv('NODE_ENV', 'production');

process.env.NODE_ENV === 'production';
import.meta.env.NODE_ENV === 'production';

vi.stubEnv('NODE_ENV', 'staging');

process.env.NODE_ENV === 'staging';
import.meta.env.NODE_ENV === 'staging';

vi.unstubAllEnvs();

// stellt den Wert wieder her, der vor dem ersten "stubEnv"-Aufruf gespeichert wurde
process.env.NODE_ENV === 'development';
import.meta.env.NODE_ENV === 'development';

vi.stubGlobal ​

  • Typ: (name: string | number | symbol, value: unknown) => Vitest

Ändert den Wert der globalen Variablen. Du kannst ihren ursprünglichen Wert wiederherstellen, indem du vi.unstubAllGlobals aufrufst.

ts
import { vi } from 'vitest';

// `innerWidth` hat den Wert "0", bevor `stubGlobal` aufgerufen wird

vi.stubGlobal('innerWidth', 100);

innerWidth === 100;
globalThis.innerWidth === 100;
// wenn Sie jsdom oder happy-dom verwenden
window.innerWidth === 100;

TIP

Du kannst den Wert auch ändern, indem du ihn einfach globalThis oder window zuweist (wenn du die jsdom- oder happy-dom-Umgebung verwendest), aber du kannst vi.unstubAllGlobals nicht verwenden, um den ursprünglichen Wert wiederherzustellen:

ts
globalThis.innerWidth = 100;
// wenn Sie jsdom oder happy-dom verwenden
window.innerWidth = 100;

vi.unstubAllGlobals 0.26.0+ ​

  • Typ: () => Vitest

Stellt alle globalen Werte in globalThis/global (und window/top/self/parent, wenn du die jsdom- oder happy-dom-Umgebung verwendest) wieder her, die mit vi.stubGlobal geändert wurden. Wenn es zum ersten Mal aufgerufen wird, merkt sich Vitest den ursprünglichen Wert und speichert ihn, bis unstubAllGlobals erneut aufgerufen wird.

ts
import { vi } from 'vitest';

const Mock = vi.fn();

// IntersectionObserver hat den Wert "undefined", bevor `stubGlobal` aufgerufen wird

vi.stubGlobal('IntersectionObserver', Mock);

IntersectionObserver === Mock;
global.IntersectionObserver === Mock;
globalThis.IntersectionObserver === Mock;
// wenn Sie jsdom oder happy-dom verwenden
window.IntersectionObserver === Mock;

vi.unstubAllGlobals();

globalThis.IntersectionObserver === undefined;
'IntersectionObserver' in globalThis === false;
// wirft einen ReferenceError, da es nicht definiert ist
IntersectionObserver === undefined;

Fake-Timer ​

Dieser Abschnitt beschreibt die Arbeit mit Fake-Timern.

vi.advanceTimersByTime ​

  • Typ: (ms: number) => Vitest

Diese Methode führt alle initialisierten Timer aus, bis die angegebene Anzahl von Millisekunden vergangen ist oder die Timer-Warteschlange leer ist, je nachdem, was zuerst eintritt.

ts
import { vi } from 'vitest';
// ---cut---
let i = 0;
setInterval(() => console.log(++i), 50);

vi.advanceTimersByTime(150);

// log: 1
// log: 2
// log: 3

vi.advanceTimersByTimeAsync ​

  • Typ: (ms: number) => Promise<Vitest>

Diese Methode führt alle initialisierten Timer aus, bis die angegebene Anzahl von Millisekunden vergangen ist oder die Timer-Warteschlange leer ist, je nachdem, was zuerst eintritt. Asynchron gesetzte Timer werden ebenfalls berücksichtigt.

ts
import { vi } from 'vitest';
// ---cut---
let i = 0;
setInterval(() => Promise.resolve().then(() => console.log(++i)), 50);

await vi.advanceTimersByTimeAsync(150);

// log: 1
// log: 2
// log: 3

vi.advanceTimersToNextTimer ​

  • Typ: () => Vitest

Führt den nächsten verfügbaren Timer aus. Nützlich, um zwischen den einzelnen Timer-Ausführungen Überprüfungen durchzuführen. Sie können die Aufrufe verketten, um die Timer-Ausführung präzise zu steuern.

ts
import { vi } from 'vitest';
// ---cut---
let i = 0;
setInterval(() => console.log(++i), 50);

vi.advanceTimersToNextTimer() // log: 1
  .advanceTimersToNextTimer() // log: 2
  .advanceTimersToNextTimer(); // log: 3

vi.advanceTimersToNextTimerAsync ​

  • Typ: () => Promise<Vitest>

Führt den nächsten verfügbaren Timer aus und wartet, bis er abgeschlossen ist, falls er asynchron gesetzt wurde. Nützlich, um zwischen den einzelnen Timer-Ausführungen Überprüfungen durchzuführen.

ts
import { expect, vi } from 'vitest';
// ---cut---
let i = 0;
setInterval(() => Promise.resolve().then(() => console.log(++i)), 50);

await vi.advanceTimersToNextTimerAsync(); // log: 1
expect(console.log).toHaveBeenCalledWith(1);

await vi.advanceTimersToNextTimerAsync(); // log: 2
await vi.advanceTimersToNextTimerAsync(); // log: 3

vi.getTimerCount ​

  • Typ: () => number

Gibt die Anzahl der ausstehenden Timer zurück.

vi.clearAllTimers ​

Entfernt alle Timer, die zur Ausführung geplant sind. Diese Timer werden in Zukunft nicht mehr ausgeführt.

vi.getMockedSystemTime ​

  • Typ: () => Date | null

Gibt das gemockte aktuelle Datum zurück, das mit setSystemTime gesetzt wurde. Wenn das Datum nicht gemockt ist, gibt die Methode null zurück.

vi.getRealSystemTime ​

  • Typ: () => number

Wenn vi.useFakeTimers verwendet wird, werden Date.now-Aufrufe gemockt. Wenn Sie die tatsächliche Systemzeit in Millisekunden benötigen, können Sie diese Funktion aufrufen.

vi.runAllTicks ​

  • Typ: () => Vitest

Führt alle Mikrotasks aus, die durch process.nextTick in die Warteschlange gestellt wurden. Dadurch werden auch alle Mikrotasks ausgeführt, die von diesen selbst geplant wurden.

vi.runAllTimers ​

  • Typ: () => Vitest

Diese Methode führt alle initialisierten Timer aus, bis die Timer-Warteschlange leer ist. Das bedeutet, dass jeder Timer, der während der Ausführung von runAllTimers ausgelöst wird, ebenfalls ausgeführt wird. Wenn ein Intervall eine Endlosschleife verursacht, wird nach 10.000 Versuchen ein Fehler ausgelöst (dieser Grenzwert kann mit fakeTimers.loopLimit konfiguriert werden).

ts
import { vi } from 'vitest';
// ---cut---
let i = 0;
setTimeout(() => console.log(++i));
const interval = setInterval(() => {
  console.log(++i);
  if (i === 3) clearInterval(interval);
}, 50);

vi.runAllTimers();

// log: 1
// log: 2
// log: 3

vi.runAllTimersAsync ​

  • Typ: () => Promise<Vitest>

Diese Methode führt alle initialisierten Timer asynchron aus, bis die Timer-Warteschlange leer ist. Das bedeutet, dass jeder Timer, der während der Ausführung von runAllTimersAsync ausgelöst wird, ebenfalls ausgeführt wird, auch asynchrone Timer. Wenn ein Intervall eine Endlosschleife verursacht, wird nach 10.000 Versuchen ein Fehler ausgelöst (dieser Grenzwert kann mit fakeTimers.loopLimit konfiguriert werden).

ts
import { vi } from 'vitest';
// ---cut---
setTimeout(async () => {
  console.log(await Promise.resolve('result'));
}, 100);

await vi.runAllTimersAsync();

// log: result

vi.runOnlyPendingTimers ​

  • Typ: () => Vitest

Diese Methode führt alle Timer aus, die nach dem Aufruf von vi.useFakeTimers initialisiert wurden. Timer, die während der Ausführung initialisiert werden, werden nicht ausgeführt.

ts
import { vi } from 'vitest';
// ---cut---
let i = 0;
setInterval(() => console.log(++i), 50);

vi.runOnlyPendingTimers();

// log: 1

vi.runOnlyPendingTimersAsync ​

  • Typ: () => Promise<Vitest>

Diese Methode führt alle Timer asynchron aus, die nach dem Aufruf von vi.useFakeTimers initialisiert wurden, einschließlich asynchroner Timer. Timer, die während der Ausführung initialisiert werden, werden nicht ausgeführt.

ts
import { vi } from 'vitest';
// ---cut---
setTimeout(() => {
  console.log(1);
}, 100);
setTimeout(() => {
  Promise.resolve().then(() => {
    console.log(2);
    setInterval(() => {
      console.log(3);
    }, 40);
  });
}, 10);

await vi.runOnlyPendingTimersAsync();

// log: 2
// log: 3
// log: 3
// log: 1

vi.setSystemTime ​

  • Typ: (date: string | number | Date) => void

Wenn Fake-Timer aktiviert sind, simuliert diese Methode eine Änderung der Systemuhr durch den Benutzer (was sich auf datumsbezogene APIs wie hrtime, performance.now oder new Date() auswirkt). Timer werden jedoch nicht ausgelöst. Wenn Fake-Timer nicht aktiviert sind, mockt diese Methode nur Date.*-Aufrufe.

Nützlich, wenn Sie etwas testen möchten, das vom aktuellen Datum abhängt, zum Beispiel Luxon-Aufrufe in Ihrem Code.

ts
import { expect, vi } from 'vitest';
// ---cut---
const date = new Date(1998, 11, 19);

vi.useFakeTimers();
vi.setSystemTime(date);

expect(Date.now()).toBe(date.valueOf());

vi.useRealTimers();

vi.useFakeTimers ​

  • Typ: (config?: FakeTimerInstallOpts) => Vitest

Um das Mocken von Timern zu aktivieren, müssen Sie diese Methode aufrufen. Diese Methode fängt alle nachfolgenden Aufrufe von Timern ab (wie setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, clearImmediate und Date), bis vi.useRealTimers() aufgerufen wird.

Das Mocken von nextTick wird nicht unterstützt, wenn Vitest mit --pool=forks innerhalb von node:child_process ausgeführt wird. NodeJS verwendet process.nextTick intern in node:child_process und bleibt hängen, wenn es gemockt wird. Das Mocken von nextTick wird unterstützt, wenn Vitest mit --pool=threads ausgeführt wird.

Die interne Implementierung basiert auf @sinonjs/fake-timers.

TIP

Seit Version 0.35.0 wird process.nextTick nicht mehr automatisch von vi.useFakeTimers() gemockt. Es kann weiterhin gemockt werden, indem die Option im toFake-Argument angegeben wird: vi.useFakeTimers({ toFake: ['nextTick'] }).

vi.isFakeTimers 0.34.5+ ​

  • Typ: () => boolean

Gibt true zurück, wenn Fake-Timer aktiviert sind.

vi.useRealTimers ​

  • Typ: () => Vitest

Nachdem die Timer verwendet wurden, kann diese Methode aufgerufen werden, um die simulierten Timer auf ihre ursprünglichen Implementierungen zurückzusetzen. Alle zuvor geplanten Timer werden verworfen.

Sonstiges ​

Eine Sammlung nützlicher Hilfsfunktionen, die Vitest bereitstellt.

vi.waitFor 0.34.5+ ​

  • Typ: <T>(callback: WaitForCallback<T>, options?: number | WaitForOptions) => Promise<T>

Wartet, bis der Callback erfolgreich ausgeführt wurde. Wenn der Callback einen Fehler auslöst oder ein Promise ablehnt, wird so lange gewartet, bis er erfolgreich ist oder ein Timeout eintritt.

Dies ist sehr nützlich, wenn Sie warten müssen, bis eine asynchrone Aktion abgeschlossen ist, z. B. wenn Sie einen Server starten und warten müssen, bis er bereit ist.

ts
import { expect, test, vi } from 'vitest';
import { createServer } from './server.js';

test('Server started successfully', async () => {
  const server = createServer();

  await vi.waitFor(
    () => {
      if (!server.isReady) throw new Error('Server not started');

      console.log('Server started');
    },
    {
      timeout: 500, // default is 1000
      interval: 20, // default is 50
    }
  );
  expect(server.isReady).toBe(true);
});

Es funktioniert auch für asynchrone Callbacks

ts
// @vitest-environment jsdom

import { expect, test, vi } from 'vitest';
import { getDOMElementAsync, populateDOMAsync } from './dom.js';

test('Element exists in a DOM', async () => {
  // start populating DOM
  populateDOMAsync();

  const element = await vi.waitFor(
    async () => {
      // try to get the element until it exists
      const element = (await getDOMElementAsync()) as HTMLElement | null;
      expect(element).toBeTruthy();
      expect(element.dataset.initialized).toBeTruthy();
      return element;
    },
    {
      timeout: 500, // default is 1000
      interval: 20, // default is 50
    }
  );
  expect(element).toBeInstanceOf(HTMLElement);
});

Wenn vi.useFakeTimers verwendet wird, ruft vi.waitFor automatisch vi.advanceTimersByTime(interval) in jedem Check-Callback auf.

vi.waitUntil 0.34.5+ ​

  • Typ: <T>(callback: WaitUntilCallback<T>, options?: number | WaitUntilOptions) => Promise<T>

Dies ähnelt vi.waitFor, aber wenn der Callback einen Fehler auslöst, wird die Ausführung sofort unterbrochen und eine Fehlermeldung ausgegeben. Wenn der Callback einen Falsy-Wert zurückgibt, wird die nächste Prüfung so lange wiederholt, bis ein Truthy-Wert zurückgegeben wird. Dies ist nützlich, wenn Sie warten müssen, bis etwas vorhanden ist, bevor Sie den nächsten Schritt ausführen.

Betrachten Sie das folgende Beispiel. Wir können vi.waitUntil verwenden, um zu warten, bis das Element auf der Seite angezeigt wird, und dann können wir etwas mit dem Element tun.

ts
import { expect, test, vi } from 'vitest';

test('Element render correctly', async () => {
  const element = await vi.waitUntil(() => document.querySelector('.element'), {
    timeout: 500, // default is 1000
    interval: 20, // default is 50
  });

  // do something with the element
  expect(element.querySelector('.element-child')).toBeTruthy();
});

vi.hoisted 0.31.0+ ​

  • Typ: <T>(factory: () => T) => T

In ES-Modulen werden alle statischen import-Anweisungen an den Anfang der Datei verschoben (hoisted), sodass Code, der vor den Imports definiert ist, erst nach der Auswertung der Imports ausgeführt wird.

Es kann jedoch nützlich sein, einige Seiteneffekte, wie das Mocken von Daten, aufzurufen, bevor ein Modul importiert wird.

Um diese Einschränkung zu umgehen, können Sie statische Imports in dynamische umschreiben, wie folgt:

diff
callFunctionWithSideEffect()
- import { value } from './some/module.js'
+ const { value } = await import('./some/module.js')

Wenn Sie vitest ausführen, können Sie dies automatisch tun, indem Sie die Methode vi.hoisted verwenden.

diff
- callFunctionWithSideEffect()
import { value } from './some/module.js'
+ vi.hoisted(() => callFunctionWithSideEffect())

Diese Methode gibt den Wert zurück, der von der Factory zurückgegeben wurde. Sie können diesen Wert in Ihren vi.mock-Factories verwenden, wenn Sie einfachen Zugriff auf lokal definierte Variablen benötigen:

ts
import { expect, vi } from 'vitest';
import { originalMethod } from './path/to/module.js';

const { mockedMethod } = vi.hoisted(() => {
  return { mockedMethod: vi.fn() };
});

vi.mock('./path/to/module.js', () => {
  return { originalMethod: mockedMethod };
});

mockedMethod.mockReturnValue(100);
expect(originalMethod()).toBe(100);

Diese Methode kann auch asynchron aufgerufen werden, selbst wenn Ihre Umgebung kein Top-Level-Await unterstützt:

ts
const promised = await vi.hoisted(async () => {
  const response = await fetch('https://jsonplaceholder.typicode.com/posts');
  return response.json();
});

vi.setConfig ​

  • Typ: RuntimeConfig

Diese Methode aktualisiert die Konfiguration für die aktuelle Testdatei. Diese Methode unterstützt nur Konfigurationsoptionen, die sich auf die aktuelle Testdatei auswirken:

ts
vi.setConfig({
  allowOnly: true,
  testTimeout: 10_000,
  hookTimeout: 10_000,
  clearMocks: true,
  restoreMocks: true,
  fakeTimers: {
    now: new Date(2021, 11, 19),
    // supports the whole object
  },
  maxConcurrency: 10,
  sequence: {
    hooks: 'stack',
    // supports only "sequence.hooks"
  },
});

vi.resetConfig ​

  • Typ: RuntimeConfig

Wenn vi.setConfig zuvor aufgerufen wurde, wird die Konfiguration auf den Ausgangszustand zurückgesetzt.

Pager
Vorherige SeiteMock-Funktionen
Nächste Seiteexpect

Veröffentlicht unter der MIT-Lizenz.

Copyright (c) 2024 Mithril Contributors

https://v1.vitest.dev/api/vi

Veröffentlicht unter der MIT-Lizenz.

Copyright (c) 2024 Mithril Contributors