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

expect ​

Die folgenden Typen werden in den nachstehenden Typsignaturen verwendet:

ts
type Awaitable<T> = T | PromiseLike<T>;

In Vitest wird expect verwendet, um Assertions (Zusicherungen) zu erstellen. Assertions sind Funktionen, die aufgerufen werden, um eine Aussage zu überprüfen. Vitest stellt standardmäßig chai-Assertions und Jest-kompatible Assertions bereit, die auf chai aufbauen.

Beispielsweise prüft dieser Code, ob ein input-Wert gleich 2 ist. Wenn dies nicht der Fall ist, wird ein Fehler ausgelöst und der Test schlägt fehl.

ts
import { expect } from 'vitest';

const input = Math.sqrt(4);

expect(input).to.equal(2); // chai API
expect(input).toBe(2); // jest API

Technisch gesehen verwendet dieses Beispiel nicht die Funktion test, weshalb in der Konsole ein Node.js-Fehler anstelle der Vitest-Ausgabe angezeigt wird. Um mehr über test zu erfahren, lesen Sie bitte die Test API Referenz.

Zusätzlich kann expect statisch verwendet werden, um auf Matcher-Funktionen (weiter unten beschrieben) und andere Features zuzugreifen.

WARNING

expect hat keine Auswirkung auf die Typüberprüfung, wenn der Ausdruck keinen Typfehler aufweist. Um Vitest zur Typüberprüfung zu nutzen, verwenden Sie entweder expectTypeOf oder assertType.

soft ​

  • Typ: ExpectStatic & (actual: any) => Assertions

expect.soft ähnelt expect, beendet aber die Testausführung nicht bei einer fehlgeschlagenen Assertion. Stattdessen wird der Fehler als fehlgeschlagener Test markiert und die Testausführung wird fortgesetzt.

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

test('expect.soft test', () => {
  expect.soft(1 + 1).toBe(3); // Markiert den Test als fehlgeschlagen und setzt die Ausführung fort
  expect.soft(1 + 2).toBe(4); // Markiert den Test als fehlgeschlagen und setzt die Ausführung fort
});
// Am Ende des Tests werden die obigen Fehler ausgegeben.

Die Kombination mit expect ist ebenfalls möglich. Schlägt eine expect-Assertion fehl, wird der Test beendet und alle bis dahin aufgetretenen Fehler werden ausgegeben.

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

test('expect.soft test', () => {
  expect.soft(1 + 1).toBe(3); // Markiert den Test als fehlgeschlagen und setzt die Ausführung fort
  expect(1 + 2).toBe(4); // Fehlgeschlagen und beendet den Test, alle vorherigen Fehler werden ausgegeben
  expect.soft(1 + 3).toBe(5); // Wird nicht ausgeführt
});

WARNING

expect.soft kann nur innerhalb der Funktion test verwendet werden.

not ​

Die Verwendung von not kehrt die Assertion um. Beispielsweise prüft dieser Code, ob ein input-Wert nicht gleich 2 ist. Wenn er gleich ist, wird ein Fehler ausgelöst und der Test schlägt fehl.

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

const input = Math.sqrt(16);

expect(input).not.to.equal(2); // chai API
expect(input).not.toBe(2); // jest API

toBe ​

  • Typ: (value: any) => Awaitable<void>

toBe dient dazu, zu prüfen, ob primitive Datentypen gleich sind oder ob Objekte auf dieselbe Speicherstelle im Speicher verweisen. Dies entspricht dem Aufruf von expect(Object.is(3, 3)).toBe(true). Wenn die Objekte nicht identisch sind, Sie aber ihre Struktur vergleichen möchten, verwenden Sie toEqual.

Beispielsweise prüft der folgende Code, ob der Händler 13 Äpfel hat.

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

const stock = {
  type: 'apples',
  count: 13,
};

test('stock has 13 apples', () => {
  expect(stock.type).toBe('apples');
  expect(stock.count).toBe(13);
});

test('stocks are the same', () => {
  const refStock = stock; // die gleiche Referenz

  expect(stock).toBe(refStock);
});

Vermeiden Sie die Verwendung von toBe mit Fließkommazahlen, da JavaScript diese rundet und 0.1 + 0.2 nicht exakt 0.3 entspricht. Verwenden Sie stattdessen toBeCloseTo, um Fließkommazahlen zuverlässig zu vergleichen.

toBeCloseTo ​

  • Typ: (value: number, numDigits?: number) => Awaitable<void>

Verwenden Sie toBeCloseTo, um Fließkommazahlen zu vergleichen. Das optionale Argument numDigits gibt an, auf wie viele Nachkommastellen verglichen werden soll. Zum Beispiel:

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

test.fails('decimals are not equal in javascript', () => {
  expect(0.2 + 0.1).toBe(0.3); // 0.2 + 0.1 ist 0.30000000000000004
});

test('decimals are rounded to 5 after the point', () => {
  // 0.2 + 0.1 ist 0.30000 | "000000000004" entfernt
  expect(0.2 + 0.1).toBeCloseTo(0.3, 5);
  // nichts von 0.30000000000000004 wird entfernt
  expect(0.2 + 0.1).not.toBeCloseTo(0.3, 50);
});

toBeDefined ​

  • Typ: () => Awaitable<void>

toBeDefined prüft, ob ein Wert nicht undefined ist. Dies ist nützlich, um zu überprüfen, ob eine Funktion einen Wert zurückgibt.

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

function getApples() {
  return 3;
}

test('function returned something', () => {
  expect(getApples()).toBeDefined();
});

toBeUndefined ​

  • Typ: () => Awaitable<void>

Im Gegensatz zu toBeDefined prüft toBeUndefined, ob ein Wert undefined ist. Dies ist nützlich, um zu überprüfen, ob eine Funktion keinen Wert zurückgibt.

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

function getApplesFromStock(stock) {
  if (stock === 'Bill') return 13;
}

test("mary doesn't have a stock", () => {
  expect(getApplesFromStock('Mary')).toBeUndefined();
});

toBeTruthy ​

  • Typ: () => Awaitable<void>

toBeTruthy prüft, ob ein Wert bei der Konvertierung in einen booleschen Wert true ergibt. Dies ist nützlich, wenn der genaue Wert irrelevant ist, aber sichergestellt werden muss, dass er als true interpretiert wird.

Betrachten Sie beispielsweise den Rückgabewert von stocks.getInfo. Dieser kann ein komplexes Objekt, eine Zeichenkette oder ein anderer Datentyp sein. Der Code funktioniert unabhängig davon.

ts
import { Stocks } from './stocks.js';

const stocks = new Stocks();
stocks.sync('Bill');
if (stocks.getInfo('Bill')) stocks.sell('apples', 'Bill');

Um zu testen, ob stocks.getInfo einen "truthy" Wert zurückgibt, können Sie folgenden Code verwenden:

ts
import { expect, test } from 'vitest';
import { Stocks } from './stocks.js';

const stocks = new Stocks();

test('if we know Bill stock, sell apples to him', () => {
  stocks.sync('Bill');
  expect(stocks.getInfo('Bill')).toBeTruthy();
});

Alles in JavaScript ist "truthy", außer false, null, undefined, NaN, 0, -0, 0n, "" und document.all.

toBeFalsy ​

  • Typ: () => Awaitable<void>

toBeFalsy prüft, ob ein Wert bei der Konvertierung in einen booleschen Wert false ergibt. Dies ist nützlich, wenn der genaue Wert irrelevant ist, aber sichergestellt werden muss, dass er als false interpretiert wird.

Betrachten Sie beispielsweise den Rückgabewert von stocks.stockFailed. Dieser kann ein beliebiger "falsy" Wert sein, aber der Code funktioniert trotzdem.

ts
import { Stocks } from './stocks.js';

const stocks = new Stocks();
stocks.sync('Bill');
if (!stocks.stockFailed('Bill')) stocks.sell('apples', 'Bill');

Um zu testen, ob stocks.stockFailed einen "falsy" Wert zurückgibt, können Sie folgenden Code verwenden:

ts
import { expect, test } from 'vitest';
import { Stocks } from './stocks.js';

const stocks = new Stocks();

test("if Bill stock hasn't failed, sell apples to him", () => {
  stocks.syncStocks('Bill');
  expect(stocks.stockFailed('Bill')).toBeFalsy();
});

Alles in JavaScript ist "truthy", außer false, null, undefined, NaN, 0, -0, 0n, "" und document.all.

toBeNull ​

  • Typ: () => Awaitable<void>

toBeNull prüft, ob ein Wert null ist. Dies ist ein Alias für .toBe(null).

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

function apples() {
  return null;
}

test("we don't have apples", () => {
  expect(apples()).toBeNull();
});

toBeNaN ​

  • Typ: () => Awaitable<void>

toBeNaN prüft, ob ein Wert NaN ist. Dies ist ein Alias für .toBe(NaN).

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

let i = 0;

function getApplesCount() {
  i++;
  return i > 1 ? Number.NaN : i;
}

test('getApplesCount has some unusual side effects...', () => {
  expect(getApplesCount()).not.toBeNaN();
  expect(getApplesCount()).toBeNaN();
});

toBeTypeOf ​

  • Typ: (c: 'bigint' | 'boolean' | 'function' | 'number' | 'object' | 'string' | 'symbol' | 'undefined') => Awaitable<void>

toBeTypeOf prüft, ob der tatsächliche Wert dem erwarteten Datentyp entspricht.

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

const actual = 'stock';

test('stock is type of string', () => {
  expect(actual).toBeTypeOf('string');
});

toBeInstanceOf ​

  • Typ: (c: any) => Awaitable<void>

toBeInstanceOf prüft, ob der tatsächliche Wert eine Instanz der erwarteten Klasse ist.

ts
import { expect, test } from 'vitest';
import { Stocks } from './stocks.js';

const stocks = new Stocks();

test('stocks are instance of Stocks', () => {
  expect(stocks).toBeInstanceOf(Stocks);
});

toBeGreaterThan ​

  • Typ: (n: number | bigint) => Awaitable<void>

toBeGreaterThan prüft, ob der tatsächliche Wert größer als der erwartete Wert ist. Bei gleichen Werten schlägt der Test fehl.

ts
import { expect, test } from 'vitest';
import { getApples } from './stocks.js';

test('have more then 10 apples', () => {
  expect(getApples()).toBeGreaterThan(10);
});

toBeGreaterThanOrEqual ​

  • Typ: (n: number | bigint) => Awaitable<void>

toBeGreaterThanOrEqual prüft, ob der tatsächliche Wert größer oder gleich dem erwarteten Wert ist.

ts
import { expect, test } from 'vitest';
import { getApples } from './stocks.js';

test('have 11 apples or more', () => {
  expect(getApples()).toBeGreaterThanOrEqual(11);
});

toBeLessThan ​

  • Typ: (n: number | bigint) => Awaitable<void>

toBeLessThan prüft, ob der tatsächliche Wert kleiner als der erwartete Wert ist. Bei gleichen Werten schlägt der Test fehl.

ts
import { expect, test } from 'vitest';
import { getApples } from './stocks.js';

test('have less then 20 apples', () => {
  expect(getApples()).toBeLessThan(20);
});

toBeLessThanOrEqual ​

  • Typ: (n: number | bigint) => Awaitable<void>

toBeLessThanOrEqual prüft, ob der tatsächliche Wert kleiner oder gleich dem erwarteten Wert ist.

ts
import { expect, test } from 'vitest';
import { getApples } from './stocks.js';

test('have 11 apples or less', () => {
  expect(getApples()).toBeLessThanOrEqual(11);
});

toEqual ​

  • Typ: (received: any) => Awaitable<void>

toEqual prüft, ob der tatsächliche Wert gleich dem erwarteten Wert ist oder, im Falle von Objekten, die gleiche Struktur aufweist (rekursiver Vergleich). Das folgende Beispiel verdeutlicht den Unterschied zwischen toEqual und toBe:

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

const stockBill = {
  type: 'apples',
  count: 13,
};

const stockMary = {
  type: 'apples',
  count: 13,
};

test('stocks have the same properties', () => {
  expect(stockBill).toEqual(stockMary);
});

test('stocks are not the same', () => {
  expect(stockBill).not.toBe(stockMary);
});

WARNING

Für Error-Objekte wird keine tiefe Gleichheit durchgeführt. Nur die message-Eigenschaft eines Errors wird für den Gleichheitsvergleich berücksichtigt. Um die Gleichheit so anzupassen, dass andere Eigenschaften als message geprüft werden, verwenden Sie expect.addEqualityTesters. Um zu testen, ob etwas geworfen wurde, verwenden Sie die toThrowError-Assertion.

toStrictEqual ​

  • Typ: (received: any) => Awaitable<void>

toStrictEqual prüft, ob der tatsächliche Wert gleich dem erwarteten Wert ist, die gleiche Struktur aufweist (rekursiver Vergleich) und vom gleichen Typ ist.

Unterschiede zu .toEqual:

  • Es werden auch Schlüssel mit undefined-Werten berücksichtigt. Beispielsweise führt {a: undefined, b: 2} bei Verwendung von .toStrictEqual nicht zu einem positiven Vergleich mit {b: 2}.
  • Die "Dünnheit" (sparseness) von Arrays wird berücksichtigt. Beispielsweise führt [, 1] bei Verwendung von .toStrictEqual nicht zu einem positiven Vergleich mit [undefined, 1].
  • Die Objekttypen müssen übereinstimmen. Beispielsweise wird eine Klasseninstanz mit den Feldern a und b nicht als gleichwertig zu einem Literalobjekt mit den gleichen Feldern betrachtet.
ts
import { expect, test } from 'vitest';

class Stock {
  constructor(type) {
    this.type = type;
  }
}

test('structurally the same, but semantically different', () => {
  expect(new Stock('apples')).toEqual({ type: 'apples' });
  expect(new Stock('apples')).not.toStrictEqual({ type: 'apples' });
});

toContain ​

  • Typ: (received: string) => Awaitable<void>

toContain bestätigt, ob sich der tatsächliche Wert in einem Array befindet. toContain kann auch prüfen, ob eine Zeichenkette eine Teilzeichenkette einer anderen Zeichenkette ist. Seit Vitest 1.0 kann diese Assertion, wenn Sie Tests in einer browserähnlichen Umgebung ausführen, auch prüfen, ob eine Klasse in einer classList enthalten ist oder ob sich ein Element innerhalb eines anderen befindet.

ts
import { expect, test } from 'vitest';
import { getAllFruits } from './stocks.js';

test('die Fruchtliste enthält orange', () => {
  expect(getAllFruits()).toContain('orange');

  const element = document.querySelector('#el');
  // element hat eine Klasse
  expect(element.classList).toContain('flex');
  // element befindet sich innerhalb eines anderen
  expect(document.querySelector('#wrapper')).toContain(element);
});

toContainEqual ​

  • Typ: (received: any) => Awaitable<void>

toContainEqual prüft, ob ein Array ein Element mit einer bestimmten Struktur und bestimmten Werten enthält. Die Funktionsweise entspricht toEqual, angewendet auf jedes Element des Arrays.

ts
import { expect, test } from 'vitest';
import { getFruitStock } from './stocks.js';

test('apple available', () => {
  expect(getFruitStock()).toContainEqual({ fruit: 'apple', count: 5 });
});

toHaveLength ​

  • Typ: (received: number) => Awaitable<void>

toHaveLength prüft, ob ein Objekt eine .length-Eigenschaft mit einem bestimmten numerischen Wert besitzt.

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

test('toHaveLength', () => {
  expect('abc').toHaveLength(3);
  expect([1, 2, 3]).toHaveLength(3);

  expect('').not.toHaveLength(3); // hat keine .length-Eigenschaft mit dem Wert 3
  expect({ length: 3 }).toHaveLength(3);
});

toHaveProperty ​

  • Typ: (key: any, received?: any) => Awaitable<void>

toHaveProperty prüft, ob ein Objekt eine Eigenschaft mit dem angegebenen Schlüssel key besitzt.

Optional kann ein Wertargument angegeben werden, das mit dem Wert der Eigenschaft verglichen wird. Dieser Vergleich erfolgt mittels tiefer Gleichheit (Deep Equality), ähnlich wie beim toEqual-Matcher.

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

const invoice = {
  isActive: true,
  'P.O': '12345',
  customer: {
    first_name: 'John',
    last_name: 'Doe',
    location: 'China',
  },
  total_amount: 5000,
  items: [
    {
      type: 'apples',
      quantity: 10,
    },
    {
      type: 'oranges',
      quantity: 5,
    },
  ],
};

test('John Doe Invoice', () => {
  expect(invoice).toHaveProperty('isActive');
  expect(invoice).toHaveProperty('total_amount', 5000);

  expect(invoice).not.toHaveProperty('account');

  // Tiefe Referenzierung mittels Punktnotation
  expect(invoice).toHaveProperty('customer.first_name');
  expect(invoice).toHaveProperty('customer.last_name', 'Doe');
  expect(invoice).not.toHaveProperty('customer.location', 'India');

  // Tiefe Referenzierung mittels eines Arrays, das den Schlüssel enthält
  expect(invoice).toHaveProperty('items[0].type', 'apples');
  expect(invoice).toHaveProperty('items.0.type', 'apples');

  // Tiefe Referenzierung mit einem Array, das den KeyPath enthält
  expect(invoice).toHaveProperty(['items', 0, 'type'], 'apples');
  expect(invoice).toHaveProperty(['items', '0', 'type'], 'apples');

  // Schließen Sie Ihren Schlüssel in ein Array ein, um zu verhindern, dass er als tiefe Referenz interpretiert wird
  expect(invoice).toHaveProperty(['P.O'], '12345');
});

toMatch ​

  • Typ: (received: string | regexp) => Awaitable<void>

toMatch prüft, ob eine Zeichenkette mit einem regulären Ausdruck oder einer anderen Zeichenkette übereinstimmt.

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

test('top fruits', () => {
  expect('top fruits include apple, orange and grape').toMatch(/apple/);
  expect('applefruits').toMatch('fruit'); // toMatch akzeptiert ebenfalls einen String
});

toMatchObject ​

  • Typ: (received: object | array) => Awaitable<void>

toMatchObject prüft, ob ein Objekt mit einem Teil der Eigenschaften eines anderen Objekts übereinstimmt. Es wird geprüft, ob das erwartete Objekt im empfangenen Objekt enthalten ist.

Sie können auch ein Array von Objekten übergeben. Dies ist nützlich, um zu überprüfen, ob zwei Arrays die gleiche Anzahl an Elementen haben und die Elemente übereinstimmen. Im Gegensatz zu arrayContaining erlaubt toMatchObject keine zusätzlichen Elemente im empfangenen Array.

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

const johnInvoice = {
  isActive: true,
  customer: {
    first_name: 'John',
    last_name: 'Doe',
    location: 'China',
  },
  total_amount: 5000,
  items: [
    {
      type: 'apples',
      quantity: 10,
    },
    {
      type: 'oranges',
      quantity: 5,
    },
  ],
};

const johnDetails = {
  customer: {
    first_name: 'John',
    last_name: 'Doe',
    location: 'China',
  },
};

test('invoice has john personal details', () => {
  expect(johnInvoice).toMatchObject(johnDetails);
});

test('the number of elements must match exactly', () => {
  // stellt fest, dass ein Array von Objekten übereinstimmt
  expect([{ foo: 'bar' }, { baz: 1 }]).toMatchObject([
    { foo: 'bar' },
    { baz: 1 },
  ]);
});

toThrowError ​

  • Typ: (received: any) => Awaitable<void>

  • Alias: toThrow

toThrowError prüft, ob eine Funktion beim Aufruf einen Fehler auslöst.

Sie können optional ein Argument angeben, um zu prüfen, ob ein bestimmter Fehler ausgelöst wird:

  • Regulärer Ausdruck: Die Fehlermeldung muss dem Muster entsprechen.
  • Zeichenkette: Die Fehlermeldung muss den Text enthalten.

TIP

Sie müssen den Code in eine Funktion einbetten, da der Fehler sonst nicht abgefangen wird und der Test fehlschlägt.

Um beispielsweise zu testen, ob getFruitStock('pineapples') einen Fehler auslöst, können Sie Folgendes schreiben:

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

function getFruitStock(type: string) {
  if (type === 'pineapples') throw new Error('Pineapples are not in stock');

  // Führe andere Operationen aus
}

test('throws on pineapples', () => {
  // Überprüfen, ob die Fehlermeldung irgendwo 'stock' enthält: diese sind äquivalent
  expect(() => getFruitStock('pineapples')).toThrowError(/stock/);
  expect(() => getFruitStock('pineapples')).toThrowError('stock');

  // Testen der genauen Fehlermeldung
  expect(() => getFruitStock('pineapples')).toThrowError(
    /^Pineapples are not in stock$/
  );
});

TIP

Um asynchrone Funktionen zu testen, verwenden Sie toThrowError in Kombination mit rejects.

js
function getAsyncFruitStock() {
  return Promise.reject(new Error('empty'));
}

test('throws on pineapples', async () => {
  await expect(() => getAsyncFruitStock()).rejects.toThrowError('empty');
});

toMatchSnapshot ​

  • Typ: <T>(shape?: Partial<T> | string, message?: string) => void

Stellt sicher, dass ein Wert mit dem aktuellsten Snapshot übereinstimmt.

Sie können optional ein hint-String-Argument angeben, das an den Testnamen angehängt wird. Vitest hängt zwar immer eine Zahl an das Ende eines Snapshot-Namens an, aber kurze, beschreibende Hinweise können nützlicher sein als Zahlen, um mehrere Snapshots in einem einzelnen Testblock zu unterscheiden. Vitest sortiert Snapshots nach Namen in der entsprechenden .snap-Datei.

TIP

Wenn ein Snapshot nicht übereinstimmt und der Test fehlschlägt, können Sie die Taste u drücken, um den Snapshot einmalig zu aktualisieren. Alternativ können Sie die CLI-Optionen -u oder --update übergeben, damit Vitest die Tests immer aktualisiert.

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

test('matches snapshot', () => {
  const data = { foo: new Set(['bar', 'snapshot']) };
  expect(data).toMatchSnapshot();
});

Sie können auch eine Form eines Objekts angeben, wenn Sie nur die Struktur eines Objekts testen und keine 100%ige Übereinstimmung benötigen:

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

test('matches snapshot', () => {
  const data = { foo: new Set(['bar', 'snapshot']) };
  expect(data).toMatchSnapshot({ foo: expect.any(Set) });
});

toMatchInlineSnapshot ​

  • Typ: <T>(shape?: Partial<T> | string, snapshot?: string, message?: string) => void

Stellt sicher, dass ein Wert mit dem aktuellsten Inline-Snapshot übereinstimmt.

Vitest fügt das InlineSnapshot-String-Argument zum Matcher in der Testdatei hinzu und aktualisiert es (anstelle einer externen .snap-Datei).

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

test('matches inline snapshot', () => {
  const data = { foo: new Set(['bar', 'snapshot']) };
  // Vitest passt den folgenden Inhalt beim Aktualisieren des Snapshots an
  expect(data).toMatchInlineSnapshot(`
    {
      "foo": Set {
        "bar",
        "snapshot",
      },
    }
  `);
});

Sie können auch eine Form eines Objekts angeben, wenn Sie nur die Struktur eines Objekts testen und keine 100%ige Übereinstimmung benötigen:

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

test('matches snapshot', () => {
  const data = { foo: new Set(['bar', 'snapshot']) };
  expect(data).toMatchInlineSnapshot(
    { foo: expect.any(Set) },
    `
    {
      "foo": Any<Set>,
    }
  `
  );
});

toMatchFileSnapshot 0.30.0+ ​

  • Typ: <T>(filepath: string, message?: string) => Promise<void>

Vergleicht oder aktualisiert den Snapshot mit dem Inhalt einer explizit angegebenen Datei (anstelle der .snap-Datei).

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

it('render basic', async () => {
  const result = renderHTML(h('div', { class: 'foo' }));
  await expect(result).toMatchFileSnapshot('./test/basic.output.html');
});

Beachten Sie, dass Sie await mit toMatchFileSnapshot() verwenden müssen, da die Dateisystemoperation asynchron abläuft.

toThrowErrorMatchingSnapshot ​

  • Typ: (message?: string) => void

Funktioniert wie toMatchSnapshot, erwartet aber den gleichen Wert wie toThrowError.

toThrowErrorMatchingInlineSnapshot ​

  • Typ: (snapshot?: string, message?: string) => void

Funktioniert wie toMatchInlineSnapshot, erwartet aber den gleichen Wert wie toThrowError.

toHaveBeenCalled ​

  • Typ: () => Awaitable<void>

Diese Assertion prüft, ob eine Funktion aufgerufen wurde. Erfordert eine Mock-Funktion als Parameter für expect.

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

const market = {
  buy(subject: string, amount: number) {
    // ...
  },
};

test('spy function', () => {
  const buySpy = vi.spyOn(market, 'buy');

  expect(buySpy).not.toHaveBeenCalled();

  market.buy('apples', 10);

  expect(buySpy).toHaveBeenCalled();
});

toHaveBeenCalledTimes ​

  • Typ: (amount: number) => Awaitable<void>

Diese Assertion prüft, ob eine Funktion eine bestimmte Anzahl von Malen aufgerufen wurde. Erfordert eine Mock-Funktion als Parameter für expect.

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

const market = {
  buy(subject: string, amount: number) {
    // ...
  },
};

test('spy function called two times', () => {
  const buySpy = vi.spyOn(market, 'buy');

  market.buy('apples', 10);
  market.buy('apples', 20);

  expect(buySpy).toHaveBeenCalledTimes(2);
});

toHaveBeenCalledWith ​

  • Typ: (...args: any[]) => Awaitable<void>

Diese Assertion prüft, ob eine Funktion mindestens einmal mit bestimmten Parametern aufgerufen wurde. Erfordert eine Mock-Funktion als Parameter für expect.

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

const market = {
  buy(subject: string, amount: number) {
    // ...
  },
};

test('spy function', () => {
  const buySpy = vi.spyOn(market, 'buy');

  market.buy('apples', 10);
  market.buy('apples', 20);

  expect(buySpy).toHaveBeenCalledWith('apples', 10);
  expect(buySpy).toHaveBeenCalledWith('apples', 20);
});

toHaveBeenLastCalledWith ​

  • Typ: (...args: any[]) => Awaitable<void>

Diese Assertion prüft, ob eine Funktion bei ihrem letzten Aufruf mit bestimmten Parametern aufgerufen wurde. Erfordert eine Mock-Funktion als Parameter für expect.

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

const market = {
  buy(subject: string, amount: number) {
    // ...
  },
};

test('spy function', () => {
  const buySpy = vi.spyOn(market, 'buy');

  market.buy('apples', 10);
  market.buy('apples', 20);

  expect(buySpy).not.toHaveBeenLastCalledWith('apples', 10);
  expect(buySpy).toHaveBeenLastCalledWith('apples', 20);
});

toHaveBeenNthCalledWith ​

  • Typ: (time: number, ...args: any[]) => Awaitable<void>

Diese Assertion prüft, ob eine Funktion zum n-ten Mal mit bestimmten Parametern aufgerufen wurde. Die Nummerierung beginnt bei 1. Um also den zweiten Aufruf zu überprüfen, würden Sie .toHaveBeenNthCalledWith(2, ...) schreiben.

Erfordert eine Mock-Funktion als Parameter für expect.

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

const market = {
  buy(subject: string, amount: number) {
    // ...
  },
};

test('first call of spy function called with right params', () => {
  const buySpy = vi.spyOn(market, 'buy');

  market.buy('apples', 10);
  market.buy('apples', 20);

  expect(buySpy).toHaveBeenNthCalledWith(1, 'apples', 10);
});

toHaveReturned ​

  • Typ: () => Awaitable<void>

Diese Assertion prüft, ob eine Funktion mindestens einmal erfolgreich einen Wert zurückgegeben hat (d. h. keine Exception ausgelöst hat). Erfordert eine Mock-Funktion als Parameter für expect.

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

function getApplesPrice(amount: number) {
  const PRICE = 10;
  return amount * PRICE;
}

test('spy function returned a value', () => {
  const getPriceSpy = vi.fn(getApplesPrice);

  const price = getPriceSpy(10);

  expect(price).toBe(100);
  expect(getPriceSpy).toHaveReturned();
});

toHaveReturnedTimes ​

  • Typ: (amount: number) => Awaitable<void>

Diese Assertion prüft, ob eine Funktion genau die angegebene Anzahl an Malen erfolgreich einen Wert zurückgegeben hat (d. h. keine Exception ausgelöst hat). Erfordert eine Mock-Funktion als Parameter für expect.

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

test('spy function returns a value two times', () => {
  const sell = vi.fn((product: string) => ({ product }));

  sell('apples');
  sell('bananas');

  expect(sell).toHaveReturnedTimes(2);
});

toHaveReturnedWith ​

  • Typ: (returnValue: any) => Awaitable<void>

Mit dieser Assertion können Sie prüfen, ob eine Funktion mindestens einmal erfolgreich einen Wert mit bestimmten Parametern zurückgegeben hat. Dies erfordert, dass Sie eine Spy-Funktion an expect übergeben.

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

test('Spy-Funktion gibt ein Produkt zurück', () => {
  const sell = vi.fn((product: string) => ({ product }));

  sell('apples');

  expect(sell).toHaveReturnedWith({ product: 'apples' });
});

toHaveLastReturnedWith ​

  • Typ: (returnValue: any) => Awaitable<void>

Mit dieser Assertion können Sie prüfen, ob eine Funktion beim letzten Aufruf erfolgreich einen Wert mit bestimmten Parametern zurückgegeben hat. Dies erfordert, dass Sie eine Spy-Funktion an expect übergeben.

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

test('Spy-Funktion gibt beim letzten Aufruf Bananen zurück', () => {
  const sell = vi.fn((product: string) => ({ product }));

  sell('apples');
  sell('bananas');

  expect(sell).toHaveLastReturnedWith({ product: 'bananas' });
});

toHaveNthReturnedWith ​

  • Typ: (time: number, returnValue: any) => Awaitable<void>

Mit dieser Assertion können Sie prüfen, ob eine Funktion bei einem bestimmten Aufruf erfolgreich einen Wert mit bestimmten Parametern zurückgegeben hat. Dies erfordert, dass Sie eine Spy-Funktion an expect übergeben.

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

test('Spy-Funktion gibt beim zweiten Aufruf Bananen zurück', () => {
  const sell = vi.fn((product: string) => ({ product }));

  sell('apples');
  sell('bananas');

  expect(sell).toHaveNthReturnedWith(2, { product: 'bananas' });
});

toSatisfy ​

  • Typ: (predicate: (value: any) => boolean) => Awaitable<void>

Diese Assertion prüft, ob ein Wert ein bestimmtes Prädikat erfüllt.

ts
import { describe, expect, it } from 'vitest';
describe('toSatisfy()', () => {
  const isOdd = (value: number) => value % 2 !== 0;

  it('besteht mit 0', () => {
    expect(1).toSatisfy(isOdd);
  });

  it('besteht mit Verhandlung', () => {
    expect(2).not.toSatisfy(isOdd);
  });
});

resolves ​

  • Typ: Promisify<Assertions>

resolves vereinfacht das Assertieren von asynchronem Code. Verwenden Sie es, um den Wert eines Promises zu extrahieren und ihn mit üblichen Assertions zu prüfen. Wenn das Promise fehlschlägt (rejected wird), schlägt die Assertion fehl.

Es gibt dasselbe Assertions-Objekt zurück, aber alle Matcher geben jetzt ein Promise zurück, sodass Sie await verwenden müssen. Funktioniert auch mit chai-Assertions.

Wenn Sie beispielsweise eine Funktion haben, die einen API-Aufruf durchführt und Daten zurückgibt, können Sie diesen Code verwenden, um den Rückgabewert zu prüfen:

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

async function buyApples() {
  return fetch('/buy/apples').then(r => r.json());
}

test('buyApples gibt neue Lager-ID zurück', async () => {
  // toEqual gibt jetzt ein Promise zurück, also müssen Sie es abwarten
  await expect(buyApples()).resolves.toEqual({ id: 1 }); // jest API
  await expect(buyApples()).resolves.to.equal({ id: 1 }); // chai API
});

WARNING

Wenn die Assertion nicht mit await erwartet wird, erhalten Sie einen falsch positiven Test, der immer bestanden wird. Um sicherzustellen, dass Assertions tatsächlich ausgeführt werden, können Sie expect.assertions(number) verwenden.

rejects ​

  • Typ: Promisify<Assertions>

rejects vereinfacht das Assertieren von asynchronem Code. Verwenden Sie es, um den Grund für die Ablehnung (rejection) des Promises zu extrahieren und ihn mit üblichen Assertions zu prüfen. Wenn das Promise erfolgreich aufgelöst wird (resolved wird), schlägt die Assertion fehl.

Es gibt dasselbe Assertions-Objekt zurück, aber alle Matcher geben jetzt ein Promise zurück, sodass Sie await verwenden müssen. Funktioniert auch mit chai-Assertions.

Wenn Sie beispielsweise eine Funktion haben, die fehlschlägt, wenn Sie sie aufrufen, können Sie diesen Code verwenden, um den Grund zu prüfen:

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

async function buyApples(id) {
  if (!id) throw new Error('no id');
}

test('buyApples wirft einen Fehler aus, wenn keine ID angegeben wurde', async () => {
  // toThrow gibt jetzt ein Promise zurück, also müssen Sie es abwarten
  await expect(buyApples()).rejects.toThrow('no id');
});

WARNING

Wenn die Assertion nicht mit await erwartet wird, erhalten Sie einen falsch positiven Test, der immer bestanden wird. Um sicherzustellen, dass Assertions tatsächlich ausgeführt wurden, können Sie expect.assertions(number) verwenden.

expect.assertions ​

  • Typ: (count: number) => void

Überprüft, nachdem der Test bestanden oder fehlgeschlagen ist, ob eine bestimmte Anzahl von Assertions während eines Tests ausgeführt wurde. Dies ist nützlich, um zu prüfen, ob asynchroner Code ausgeführt wurde.

Wenn wir beispielsweise eine Funktion haben, die asynchron zwei Matcher aufruft, können wir prüfen, ob sie tatsächlich ausgeführt wurden.

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

async function doAsync(...cbs) {
  await Promise.all(cbs.map((cb, index) => cb({ index })));
}

test('alle Assertions werden ausgeführt', async () => {
  expect.assertions(2);
  function callback1(data) {
    expect(data).toBeTruthy();
  }
  function callback2(data) {
    expect(data).toBeTruthy();
  }

  await doAsync(callback1, callback2);
});

WARNING

Bei Verwendung von assertions mit asynchronen, gleichzeitigen Tests muss expect aus dem lokalen Testkontext verwendet werden, um sicherzustellen, dass der richtige Test erkannt wird.

expect.hasAssertions ​

  • Typ: () => void

Überprüft, nachdem der Test bestanden oder fehlgeschlagen ist, ob mindestens eine Assertion während eines Tests aufgerufen wurde. Dies ist nützlich, um zu prüfen, ob asynchroner Code aufgerufen wurde.

Wenn Sie beispielsweise Code haben, der einen Callback aufruft, können wir eine Assertion innerhalb eines Callbacks machen, aber der Test würde trotzdem bestanden, selbst wenn keine Assertion aufgerufen wurde.

ts
import { expect, test } from 'vitest';
import { db } from './db.js';

const cbs = [];

function onSelect(cb) {
  cbs.push(cb);
}

// nach dem Auswählen aus der Datenbank rufen wir alle Callbacks auf
function select(id) {
  return db.select({ id }).then(data => {
    return Promise.all(cbs.map(cb => cb(data)));
  });
}

test('Der Callback wurde aufgerufen', async () => {
  expect.hasAssertions();
  onSelect(data => {
    // sollte bei select aufgerufen werden
    expect(data).toBeTruthy();
  });
  // wenn nicht mit `await` erwartet, schlägt der Test fehl
  // wenn Sie expect.hasAssertions() nicht haben, wird der Test bestanden
  await select(3);
});

expect.unreachable ​

  • Typ: (message?: string) => never

Diese Methode wird verwendet, um zu bestätigen, dass eine bestimmte Codezeile niemals erreicht werden sollte.

Wenn wir beispielsweise testen möchten, dass build() aufgrund des Empfangs von Verzeichnissen ohne src-Ordner einen Fehler auslöst, und auch jeden Fehler separat behandeln möchten, könnten wir Folgendes tun:

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

async function build(dir) {
  if (dir.includes('no-src')) throw new Error(`${dir}/src does not exist`);
}

const errorDirs = [
  'no-src-folder',
  // ...
];

test.each(errorDirs)('build schlägt mit "%s" fehl', async dir => {
  try {
    await build(dir);
    expect.unreachable('Der Build sollte nicht bestehen');
  } catch (err: any) {
    expect(err).toBeInstanceOf(Error);
    expect(err.stack).toContain('build');

    switch (dir) {
      case 'no-src-folder':
        expect(err.message).toBe(`${dir}/src does not exist`);
        break;
      default:
        // um alle Fehlerfälle abzudecken
        expect.unreachable('Alle Fehlertests müssen behandelt werden');
        break;
    }
  }
});

expect.anything ​

  • Typ: () => any

Dieser asymmetrische Matcher gibt bei Verwendung mit einer Gleichheitsprüfung immer true zurück. Nützlich, wenn Sie nur sicherstellen möchten, dass die Eigenschaft vorhanden ist.

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

test('Objekt hat den Schlüssel "apples"', () => {
  expect({ apples: 22 }).toEqual({ apples: expect.anything() });
});

expect.any ​

  • Typ: (constructor: unknown) => any

Dieser asymmetrische Matcher gibt bei Verwendung mit einer Gleichheitsprüfung nur dann true zurück, wenn der Wert eine Instanz eines angegebenen Konstruktors ist. Nützlich, wenn Sie einen Wert haben, der jedes Mal generiert wird, und Sie nur wissen möchten, dass er mit einem geeigneten Typ vorhanden ist.

ts
import { expect, test } from 'vitest';
import { generateId } from './generators.js';

test('"id" ist eine Zahl', () => {
  expect({ id: generateId() }).toEqual({ id: expect.any(Number) });
});

expect.closeTo 1.0.0+ ​

  • Typ: (expected: any, precision?: number) => any

expect.closeTo ist nützlich, wenn Gleitkommazahlen in Objekteigenschaften oder Array-Elementen verglichen werden sollen. Wenn Sie eine Zahl vergleichen müssen, verwenden Sie stattdessen .toBeCloseTo.

Das optionale Argument numDigits begrenzt die Anzahl der zu prüfenden Stellen nach dem Dezimalpunkt. Für den Standardwert 2 ist das Testkriterium Math.abs(expected - received) < 0.005 (d. h. 10 ** -2 / 2).

Beispielsweise besteht dieser Test mit einer Genauigkeit von 5 Stellen:

js
test('Vergleiche Float in Objekteigenschaften', () => {
  expect({
    title: '0.1 + 0.2',
    sum: 0.1 + 0.2,
  }).toEqual({
    title: '0.1 + 0.2',
    sum: expect.closeTo(0.3, 5),
  });
});

expect.arrayContaining ​

  • Typ: <T>(expected: T[]) => any

Bei Verwendung mit einer Gleichheitsprüfung gibt dieser asymmetrische Matcher true zurück, wenn der Wert ein Array ist und die angegebenen Elemente enthält.

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

test('Der Korb enthält Fuji-Äpfel', () => {
  const basket = {
    varieties: ['Empire', 'Fuji', 'Gala'],
    count: 3,
  };
  expect(basket).toEqual({
    count: 3,
    varieties: expect.arrayContaining(['Fuji']),
  });
});

TIP

Sie können expect.not mit diesem Matcher verwenden, um den erwarteten Wert zu negieren.

expect.objectContaining ​

  • Typ: (expected: any) => any

Bei Verwendung mit einer Gleichheitsprüfung gibt dieser asymmetrische Matcher true zurück, wenn der Wert eine ähnliche Form hat.

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

test('Der Korb hat Empire-Äpfel', () => {
  const basket = {
    varieties: [
      {
        name: 'Empire',
        count: 1,
      },
    ],
  };
  expect(basket).toEqual({
    varieties: [expect.objectContaining({ name: 'Empire' })],
  });
});

TIP

Sie können expect.not mit diesem Matcher verwenden, um den erwarteten Wert zu negieren.

expect.stringContaining ​

  • Typ: (expected: any) => any

Bei Verwendung mit einer Gleichheitsprüfung gibt dieser asymmetrische Matcher true zurück, wenn der Wert eine Zeichenkette ist und eine angegebene Teilzeichenkette enthält.

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

test('Die Apfelsorte enthält "Emp" im Namen', () => {
  const variety = {
    name: 'Empire',
    count: 1,
  };
  expect(variety).toEqual({
    name: expect.stringContaining('Emp'),
    count: 1,
  });
});

TIP

Sie können expect.not mit diesem Matcher verwenden, um den erwarteten Wert zu negieren.

expect.stringMatching ​

  • Typ: (expected: any) => any

Bei Verwendung mit einer Gleichheitsprüfung gibt dieser asymmetrische Matcher true zurück, wenn der Wert eine Zeichenkette ist und eine angegebene Teilzeichenkette enthält oder wenn die Zeichenkette einem regulären Ausdruck entspricht.

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

test('Die Sorte endet mit "re"', () => {
  const variety = {
    name: 'Empire',
    count: 1,
  };
  expect(variety).toEqual({
    name: expect.stringMatching(/re$/),
    count: 1,
  });
});

TIP

Sie können expect.not mit diesem Matcher verwenden, um den erwarteten Wert zu negieren.

expect.addSnapshotSerializer ​

  • Typ: (plugin: PrettyFormatPlugin) => void

Diese Methode fügt benutzerdefinierte Serialisierer hinzu, die beim Erstellen eines Snapshots aufgerufen werden. Dies ist eine erweiterte Funktion - wenn Sie mehr erfahren möchten, lesen Sie bitte eine Anleitung zu benutzerdefinierten Serialisierern.

Wenn Sie benutzerdefinierte Serialisierer hinzufügen, sollten Sie diese Methode innerhalb von setupFiles aufrufen. Dies wirkt sich auf jeden Snapshot aus.

TIP

Wenn Sie zuvor Vue CLI mit Jest verwendet haben, sollten Sie jest-serializer-vue installieren. Andernfalls werden Ihre Snapshots in eine Zeichenkette eingeschlossen, wodurch die Zeichen " maskiert werden müssen.

expect.extend ​

  • Typ: (matchers: MatchersObject) => void

Sie können Standard-Matcher mit Ihren eigenen erweitern. Diese Funktion wird verwendet, um das Matcher-Objekt mit benutzerdefinierten Matchern zu erweitern.

Wenn Sie Matcher auf diese Weise definieren, erstellen Sie auch asymmetrische Matcher, die wie expect.stringContaining verwendet werden können.

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

test('Benutzerdefinierte Matcher', () => {
  expect.extend({
    toBeFoo: (received, expected) => {
      if (received !== 'foo') {
        return {
          message: () => `erwartet, dass ${received} gleich foo ist`,
          pass: false,
        };
      }
    },
  });

  expect('foo').toBeFoo();
  expect({ foo: 'foo' }).toEqual({ foo: expect.toBeFoo() });
});

TIP

Wenn Ihre Matcher in jedem Test verfügbar sein sollen, sollten Sie diese Methode innerhalb von setupFiles aufrufen.

Diese Funktion ist mit Jests expect.extend kompatibel, sodass jede Bibliothek, die sie zum Erstellen benutzerdefinierter Matcher verwendet, mit Vitest funktioniert.

Wenn Sie TypeScript verwenden, können Sie seit Vitest 0.31.0 die Standard-Assertion-Schnittstelle in einer Ambient-Deklarationsdatei (z. B. vitest.d.ts) mit dem folgenden Code erweitern:

ts
interface CustomMatchers<R = unknown> {
  toBeFoo: () => R;
}

declare module 'vitest' {
  interface Assertion<T = any> extends CustomMatchers<T> {}
  interface AsymmetricMatchersContaining extends CustomMatchers {}
}

WARNING

Vergessen Sie nicht, die Ambient-Deklarationsdatei in Ihre tsconfig.json aufzunehmen.

TIP

Wenn Sie mehr erfahren möchten, lesen Sie die Anleitung zum Erweitern von Matchern.

expect.addEqualityTesters 1.2.0+ ​

  • Typ: (tester: Array<Tester>) => void

Sie können diese Methode verwenden, um benutzerdefinierte Tester zu definieren. Dies sind Methoden, die von Matchern verwendet werden, um zu testen, ob zwei Objekte gleich sind. Es ist mit expect.addEqualityTesters von Jest kompatibel.

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

class AnagramComparator {
  public word: string;

  constructor(word: string) {
    this.word = word;
  }

  equals(other: AnagramComparator): boolean {
    const cleanStr1 = this.word.replace(/ /g, '').toLowerCase();
    const cleanStr2 = other.word.replace(/ /g, '').toLowerCase();

    const sortedStr1 = cleanStr1.split('').sort().join('');
    const sortedStr2 = cleanStr2.split('').sort().join('');

    return sortedStr1 === sortedStr2;
  }
}

function isAnagramComparator(a: unknown): a is AnagramComparator {
  return a instanceof AnagramComparator;
}

function areAnagramsEqual(a: unknown, b: unknown): boolean | undefined {
  const isAAnagramComparator = isAnagramComparator(a);
  const isBAnagramComparator = isBAnagramComparator(b);

  if (isAAnagramComparator && isBAnagramComparator) return a.equals(b);
  else if (isAAnagramComparator === isBAnagramComparator) return undefined;
  else return false;
}

expect.addEqualityTesters([areAnagramsEqual]);

test('benutzerdefinierter Gleichheitstester', () => {
  expect(new AnagramComparator('listen')).toEqual(
    new AnagramComparator('silent')
  );
});
Pager
Vorherige SeiteVi
Nächste SeiteexpectTypeOf

Veröffentlicht unter der MIT-Lizenz.

Copyright (c) 2024 Mithril Contributors

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

Veröffentlicht unter der MIT-Lizenz.

Copyright (c) 2024 Mithril Contributors