Skip to content
Vitest 3
Main Navigation Leitfaden & APIKonfigurationBrowser-ModusFortgeschritten API
3.2.0
2.1.9
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

Einführung

Warum Vitest

Erste Schritte

Funktionen

Vitest konfigurieren

API

Test-API-Referenz

Mock-Funktionen

Vi

expect

expectTypeOf

assert

assertType

Leitfaden

Befehlszeilenschnittstelle

Testfilterung

Testprojekte

Reporter

Code-Abdeckung

Snapshot

Mocking

Parallelisierung

Typüberprüfungen

Vitest UI

Tests im Quellcode

Test-Kontext

Test-Annotationen

Testumgebung

Matcher erweitern

IDE-Integrationen

Debugging

Häufige Fehler

Migrationsleitfaden

Migration zu Vitest 3.0

Migration von Jest

Performance

Leistungsprofilierung von Tests

Leistung verbessern

Browser-Modus

Erweiterte API

Vergleiche mit anderen Test-Runnern

Auf dieser Seite

expect ​

Gerne, hier ist die optimierte deutsche Version Ihres Vitest 3-Dokuments:

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

expect wird verwendet, um Zusicherungen (Assertions) zu erstellen. In diesem Kontext sind Assertions Funktionen, die aufgerufen werden, um eine Aussage zu überprüfen. Vitest bietet standardmäßig chai-Assertions sowie Jest-kompatible Assertions, die auf chai basieren. Im Gegensatz zu Jest unterstützt Vitest eine Nachricht als zweites Argument: Schlägt die Assertion fehl, wird diese Nachricht als Fehlermeldung ausgegeben.

ts
export interface ExpectStatic
  extends Chai.ExpectStatic,
    AsymmetricMatchersContaining {
  <T>(actual: T, message?: string): Assertion<T>;
  extend: (expects: MatchersObject) => void;
  anything: () => any;
  any: (constructor: unknown) => any;
  getState: () => MatcherState;
  setState: (state: Partial<MatcherState>) => void;
  not: AsymmetricMatchersContaining;
}

Zum Beispiel bestätigt dieser Code, dass ein input-Wert gleich 2 ist. Andernfalls löst die Assertion einen Fehler aus, 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 keine test-Funktion, sodass 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.

Darüber hinaus kann expect statisch verwendet werden, um auf später beschriebene Matcher-Funktionen und weitere Funktionalitäten zuzugreifen.

WARNING

expect beeinflusst die Typüberprüfung nicht, wenn der Ausdruck keinen Typfehler aufweist. Wenn Sie Vitest als Typ-Checker nutzen möchten, verwenden Sie expectTypeOf oder assertType.

soft ​

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

expect.soft funktioniert ähnlich wie expect, aber anstatt die Testausführung bei einer fehlgeschlagenen Assertion zu beenden, setzt es die Ausführung fort und markiert den Fehler als Testfehler. Alle während des Tests aufgetretenen Fehler werden angezeigt, bis der Test vollständig durchgelaufen ist.

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

test('expect.soft test', () => {
  expect.soft(1 + 1).toBe(3); // markiert den Test als fehlgeschlagen und fährt fort
  expect.soft(1 + 2).toBe(4); // markiert den Test als fehlgeschlagen und fährt fort
});
// Der Reporter meldet beide Fehler am Ende der Ausführung

Es kann auch in Kombination mit expect verwendet werden. Wenn eine expect-Assertion fehlschlägt, wird der Test beendet und alle vorherigen Fehler werden angezeigt.

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

test('expect.soft test', () => {
  expect.soft(1 + 1).toBe(3); // markiert den Test als fehlgeschlagen und fährt fort
  expect(1 + 2).toBe(4); // schlägt fehl 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 test-Funktion verwendet werden.

poll ​

ts
interface ExpectPoll extends ExpectStatic {
  (actual: () => T, options: { interval; timeout; message }): Promise<
    Assertions<T>
  >;
}

expect.poll führt die Assertion wiederholt aus, bis sie erfolgreich ist. Sie können konfigurieren, wie oft Vitest den expect.poll-Callback erneut ausführen soll, indem Sie die Optionen interval und timeout festlegen.

Tritt im expect.poll-Callback ein Fehler auf, wiederholt Vitest den Versuch, bis das Timeout abläuft.

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

test('element exists', async () => {
  asyncInjectElement();

  await expect.poll(() => document.querySelector('.element')).toBeTruthy();
});

WARNING

expect.poll macht jede Assertion asynchron, daher müssen Sie asynchron darauf warten. Seit Vitest 3 schlägt der Test fehl, wenn Sie vergessen, asynchron darauf zu warten, und gibt eine entsprechende Warnung aus.

expect.poll funktioniert nicht mit mehreren Matchern:

  • Snapshot-Matcher werden nicht unterstützt, da sie immer erfolgreich sind. Wenn Ihre Bedingung unzuverlässig ist, verwenden Sie stattdessen vi.waitFor, um sie zuerst aufzulösen:
ts
import { expect, vi } from 'vitest';

const flakyValue = await vi.waitFor(() => getFlakyValue());
expect(flakyValue).toMatchSnapshot();
  • .resolves und .rejects werden nicht unterstützt. expect.poll wartet bereits asynchron auf die Bedingung, wenn diese asynchron ist.
  • toThrow und seine Aliase werden nicht unterstützt, da die expect.poll-Bedingung immer aufgelöst wird, bevor der Matcher den Wert empfängt.

not ​

Mit not wird die Assertion negiert. Zum Beispiel bestätigt dieser Code, dass ein input-Wert nicht gleich 2 ist. Wenn er gleich ist, löst die Assertion einen Fehler aus, 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 kann verwendet werden, um zu bestätigen, ob Primitive gleich sind oder ob Objekte dieselbe Referenz teilen. Es ist äquivalent zum Aufruf von expect(Object.is(3, 3)).toBe(true). Wenn die Objekte nicht identisch sind, Sie aber ihre Strukturen prüfen möchten, können Sie toEqual verwenden.

Zum Beispiel 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; // gleiche Referenz

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

Vermeiden Sie es, toBe mit Gleitkommazahlen zu verwenden. Da JavaScript sie rundet, ist 0.1 + 0.2 nicht exakt 0.3. Um Gleitkommazahlen zuverlässig zu bestätigen, verwenden Sie die Assertion toBeCloseTo.

toBeCloseTo ​

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

Verwenden Sie toBeCloseTo, um Gleitkommazahlen zu vergleichen. Das optionale Argument numDigits begrenzt die Anzahl der zu prüfenden Ziffern nach dem Dezimalpunkt. Zum Beispiel:

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

test.fails('Dezimalzahlen sind in JavaScript nicht gleich', () => {
  expect(0.2 + 0.1).toBe(0.3); // 0.2 + 0.1 ist 0.30000000000000004
});

test('Dezimalzahlen werden auf 5 Stellen nach dem Komma gerundet', () => {
  // 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 bestätigt, dass der Wert nicht gleich undefined ist. Ein nützlicher Anwendungsfall ist es, zu prüfen, ob eine Funktion etwas zurückgegeben hat.

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

function getApples() {
  return 3;
}

test('Funktion hat etwas zurückgegeben', () => {
  expect(getApples()).toBeDefined();
});

toBeUndefined ​

  • Typ: () => Awaitable<void>

Im Gegensatz zu toBeDefined bestätigt toBeUndefined, dass der Wert gleich undefined ist. Ein nützlicher Anwendungsfall ist es, zu prüfen, ob eine Funktion nichts zurückgegeben hat.

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

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

test("Mary hat keinen Bestand", () => {
  expect(getApplesFromStock('Mary')).toBeUndefined();
});

toBeTruthy ​

  • Typ: () => Awaitable<void>

toBeTruthy bestätigt, dass der Wert true ist, wenn er in einen booleschen Wert umgewandelt wird. Nützlich, wenn Ihnen der genaue Wert unwichtig ist, Sie aber nur wissen möchten, ob er in true umgewandelt werden kann.

Zum Beispiel spielt bei diesem Code der Rückgabewert von stocks.getInfo keine Rolle – es kann ein komplexes Objekt, ein String oder etwas anderes sein. Der Code funktioniert trotzdem.

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

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

Wenn Sie also testen möchten, dass stocks.getInfo truthy ist, könnten Sie schreiben:

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

const stocks = new Stocks();

test('wenn wir Bills Bestand kennen, verkaufen wir ihm Äpfel', () => {
  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 bestätigt, dass der Wert false ist, wenn er in einen booleschen Wert umgewandelt wird. Nützlich, wenn Ihnen der genaue Wert unwichtig ist, Sie aber nur wissen möchten, ob er in false umgewandelt werden kann.

Zum Beispiel spielt bei diesem Code der Rückgabewert von stocks.stockFailed keine Rolle – er kann jeden falsy Wert zurückgeben, 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');
}

Wenn Sie also testen möchten, dass stocks.stockFailed falsy ist, könnten Sie schreiben:

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

const stocks = new Stocks();

test("wenn Bills Bestand nicht fehlgeschlagen ist, verkaufen wir ihm Äpfel", () => {
  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 bestätigt einfach, ob etwas null ist. Alias für .toBe(null).

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

function apples() {
  return null;
}

test("wir haben keine Äpfel", () => {
  expect(apples()).toBeNull();
});

toBeNaN ​

  • Typ: () => Awaitable<void>

toBeNaN prüft einfach, ob etwas NaN ist. 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 hat einige ungewöhnliche Nebeneffekte...', () => {
  expect(getApplesCount()).not.toBeNaN();
  expect(getApplesCount()).toBeNaN();
});

toBeOneOf ​

  • Typ: (sample: Array<any>) => any

toBeOneOf bestätigt, ob ein Wert mit einem der Werte im bereitgestellten Array übereinstimmt.

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

test('Frucht ist einer der erlaubten Werte', () => {
  expect(fruit).toBeOneOf(['Apfel', 'Banane', 'Orange']);
});

Der asymmetrische Matcher ist besonders nützlich beim Testen optionaler Eigenschaften, die entweder null oder undefined sein können:

ts
test('optionale Eigenschaften können null oder undefined sein', () => {
  const user = {
    firstName: 'John',
    middleName: undefined,
    lastName: 'Doe',
  };

  expect(user).toEqual({
    firstName: expect.any(String),
    middleName: expect.toBeOneOf([expect.any(String), undefined]),
    lastName: expect.any(String),
  });
});

TIP

Sie können expect.not mit diesem Matcher verwenden, um sicherzustellen, dass ein Wert NICHT mit einer der bereitgestellten Optionen übereinstimmt.

toBeTypeOf ​

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

toBeTypeOf bestätigt, ob ein tatsächlicher Wert vom Typ des erwarteten Typs ist.

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

const actual = 'stock';

test('stock ist vom Typ string', () => {
  expect(actual).toBeTypeOf('string');
});

toBeInstanceOf ​

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

toBeInstanceOf bestätigt, ob ein tatsächlicher Wert eine Instanz der empfangenen Klasse ist.

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

const stocks = new Stocks();

test('stocks sind Instanz von Stocks', () => {
  expect(stocks).toBeInstanceOf(Stocks);
});

toBeGreaterThan ​

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

toBeGreaterThan bestätigt, ob der tatsächliche Wert größer ist als der empfangene. Gleiche Werte führen zum Fehlschlagen des Tests.

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

test('habe mehr als 10 Äpfel', () => {
  expect(getApples()).toBeGreaterThan(10);
});

toBeGreaterThanOrEqual ​

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

toBeGreaterThanOrEqual bestätigt, ob der tatsächliche Wert größer oder gleich dem empfangenen ist.

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

test('habe 11 Äpfel oder mehr', () => {
  expect(getApples()).toBeGreaterThanOrEqual(11);
});

toBeLessThan ​

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

toBeLessThan bestätigt, ob der tatsächliche Wert kleiner ist als der empfangene. Gleiche Werte führen zum Fehlschlagen des Tests.

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

test('habe weniger als 20 Äpfel', () => {
  expect(getApples()).toBeLessThan(20);
});

toBeLessThanOrEqual ​

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

toBeLessThanOrEqual bestätigt, ob der tatsächliche Wert kleiner oder gleich dem empfangenen ist.

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

test('habe 11 Äpfel oder weniger', () => {
  expect(getApples()).toBeLessThanOrEqual(11);
});

toEqual ​

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

toEqual bestätigt, ob der tatsächliche Wert dem empfangenen entspricht oder dieselbe Struktur hat, wenn es sich um ein Objekt handelt (vergleicht sie rekursiv). Den Unterschied zwischen toEqual und toBe können Sie in diesem Beispiel sehen:

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

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

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

test('Bestände haben die gleichen Eigenschaften', () => {
  expect(stockBill).toEqual(stockMary);
});

test('Bestände sind nicht gleich', () => {
  expect(stockBill).not.toBe(stockMary);
});

WARNING

Bei Error-Objekten werden auch nicht-enumerierbare Eigenschaften wie name, message, cause und AggregateError.errors verglichen. Für Error.cause wird der Vergleich asymmetrisch durchgeführt:

ts
// Erfolg
expect(new Error('hi', { cause: 'x' })).toEqual(new Error('hi'));

// Fehler
expect(new Error('hi')).toEqual(new Error('hi', { cause: 'x' }));

Um zu testen, ob etwas geworfen wurde, verwenden Sie die Assertion toThrowError.

toStrictEqual ​

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

toStrictEqual bestätigt, ob der tatsächliche Wert dem empfangenen entspricht oder dieselbe Struktur hat, wenn es sich um ein Objekt handelt (vergleicht sie rekursiv), und vom selben Typ ist.

Unterschiede zu .toEqual:

  • Schlüssel mit undefined-Eigenschaften werden geprüft. Z.B. {a: undefined, b: 2} stimmt nicht mit {b: 2} überein, wenn .toStrictEqual verwendet wird.
  • Die Spärlichkeit von Arrays wird geprüft. Z.B. [, 1] stimmt nicht mit [undefined, 1] überein, wenn .toStrictEqual verwendet wird.
  • Objekttypen werden auf Gleichheit geprüft. Z.B. Eine Klasseninstanz mit den Feldern a und b entspricht nicht einem Literalobjekt mit den Feldern a und b.
ts
import { expect, test } from 'vitest';

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

test('strukturell gleich, aber semantisch unterschiedlich', () => {
  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 der tatsächliche Wert in einem Array enthalten ist. toContain kann auch prüfen, ob ein String ein Substring eines anderen Strings ist. Wenn Sie Tests in einer browserähnlichen Umgebung ausführen, kann diese Assertion auch prüfen, ob eine Klasse in einer classList enthalten ist oder ein Element in einem anderen Element enthalten ist.

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 ist in einem anderen enthalten
  expect(document.querySelector('#wrapper')).toContain(element);
});

toContainEqual ​

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

toContainEqual bestätigt, ob ein Element mit einer bestimmten Struktur und Werten in einem Array enthalten ist. Es funktioniert intern wie toEqual für jedes Element.

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

test('Apfel verfügbar', () => {
  expect(getFruitStock()).toContainEqual({ fruit: 'apple', count: 5 });
});

toHaveLength ​

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

toHaveLength bestätigt, ob ein Objekt eine .length-Eigenschaft hat und diese auf einen bestimmten numerischen Wert gesetzt ist.

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 von 3
  expect({ length: 3 }).toHaveLength(3);
});

toHaveProperty ​

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

toHaveProperty bestätigt, ob eine Eigenschaft am angegebenen Referenzschlüssel key für ein Objekt existiert.

Sie können auch ein optionales Wertargument angeben, das auch als tiefe Gleichheit bekannt ist, ähnlich dem toEqual-Matcher, um den empfangenen Eigenschaftswert zu vergleichen.

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 Rechnung', () => {
  expect(invoice).toHaveProperty('isActive'); // bestätigt, dass der Schlüssel existiert
  expect(invoice).toHaveProperty('total_amount', 5000); // bestätigt, dass der Schlüssel existiert und der Wert gleich ist

  expect(invoice).not.toHaveProperty('account'); // bestätigt, dass dieser Schlüssel nicht existiert

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

  // Tiefe Referenzierung mit einem Array, das den Schlüssel enthält
  expect(invoice).toHaveProperty('items[0].type', 'apples');
  expect(invoice).toHaveProperty('items.0.type', 'apples'); // Punktnotation funktioniert auch

  // Tiefe Referenzierung mit einem Array, das den Schlüsselpfad enthält
  expect(invoice).toHaveProperty(['items', 0, 'type'], 'apples');
  expect(invoice).toHaveProperty(['items', '0', 'type'], 'apples'); // String-Notation funktioniert auch

  // Umschließen Sie Ihren Schlüssel in einem Array, um zu vermeiden, dass der Schlüssel als tiefe Referenz geparst wird
  expect(invoice).toHaveProperty(['P.O'], '12345');
});

toMatch ​

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

toMatch bestätigt, ob ein String einem regulären Ausdruck oder einem String entspricht.

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

test('Top-Früchte', () => {
  expect('Top-Früchte sind Apfel, Orange und Traube').toMatch(/apple/);
  expect('Apfelfrüchte').toMatch('Frucht'); // toMatch akzeptiert auch einen String
});

toMatchObject ​

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

toMatchObject bestätigt, ob ein Objekt einer Teilmenge der Eigenschaften eines Objekts entspricht.

Sie können auch ein Array von Objekten übergeben. Dies ist nützlich, wenn Sie prüfen möchten, ob zwei Arrays die gleiche Anzahl von Elementen haben, im Gegensatz zu arrayContaining, das zusätzliche Elemente im empfangenen Array zulässt.

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('Rechnung enthält Johns persönliche Daten', () => {
  expect(johnInvoice).toMatchObject(johnDetails);
});

test('die Anzahl der Elemente muss exakt übereinstimmen', () => {
  // Bestätigen, 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 bestätigt, ob eine Funktion einen Fehler wirft, wenn sie aufgerufen wird.

Sie können ein optionales Argument angeben, um zu testen, ob ein bestimmter Fehler geworfen wird:

  • RegExp: Fehlermeldung entspricht dem Muster
  • string: Fehlermeldung enthält den Substring
  • Error, AsymmetricMatcher: Vergleich mit einem empfangenen Objekt ähnlich toEqual(received)

TIP

Sie müssen den Code in eine Funktion einschließen, da der Fehler andernfalls nicht abgefangen wird und der Test fehlschlägt.

Dies gilt nicht für asynchrone Aufrufe, da rejects das Promise korrekt auflöst:

ts
test('expect rejects toThrow', async ({ expect }) => {
  const promise = Promise.reject(new Error('Test'));
  await expect(promise).rejects.toThrowError();
});

Wenn wir zum Beispiel testen möchten, dass getFruitStock('pineapples') einen Fehler wirft, könnten wir schreiben:

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

function getFruitStock(type: string) {
  if (type === 'pineapples') {
    throw new Error('Ananas sind nicht auf Lager');
  }

  // Mache andere Dinge
}

test('wirft bei Ananas', () => {
  // Teste, dass die Fehlermeldung irgendwo "stock" enthält: diese sind äquivalent
  expect(() => getFruitStock('pineapples')).toThrowError(/stock/);
  expect(() => getFruitStock('pineapples')).toThrowError('stock');

  // Teste die exakte Fehlermeldung
  expect(() => getFruitStock('pineapples')).toThrowError(
    /^Ananas sind nicht auf Lager$/
  );

  expect(() => getFruitStock('pineapples')).toThrowError(
    new Error('Ananas sind nicht auf Lager')
  );
  expect(() => getFruitStock('pineapples')).toThrowError(
    expect.objectContaining({
      message: 'Ananas sind nicht auf Lager',
    })
  );
});

TIP

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

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

test('wirft bei Ananas', async () => {
  await expect(() => getAsyncFruitStock()).rejects.toThrowError('empty');
});

toMatchSnapshot ​

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

Dies stellt sicher, dass ein Wert mit dem neuesten Snapshot übereinstimmt.

Sie können ein optionales hint-String-Argument angeben, das an den Testnamen angehängt wird. Obwohl Vitest immer eine Zahl am Ende eines Snapshot-Namens hinzufügt, können kurze, beschreibende Hinweise nützlicher sein als Zahlen, um mehrere Snapshots in einem einzelnen it- oder test-Block zu unterscheiden. Vitest sortiert Snapshots nach Namen in der entsprechenden .snap-Datei.

TIP

Wenn ein Snapshot nicht übereinstimmt und zum Fehlschlagen des Tests führt, können Sie, wenn die Nichtübereinstimmung erwartet wird, die Taste u drücken, um den Snapshot einmal zu aktualisieren. Oder Sie können die CLI-Optionen -u oder --update übergeben, damit Vitest die Tests immer aktualisiert.

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

test('stimmt mit Snapshot überein', () => {
  const data = { foo: new Set(['bar', 'snapshot']) };
  expect(data).toMatchSnapshot();
});

Sie können auch eine Form eines Objekts angeben, wenn Sie nur die Form eines Objekts testen und es nicht zu 100% kompatibel sein muss:

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

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

toMatchInlineSnapshot ​

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

Dies stellt sicher, dass ein Wert mit dem aktuellsten 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('stimmt mit Inline-Snapshot überein', () => {
  const data = { foo: new Set(['bar', 'snapshot']) };
  // Vitest aktualisiert den folgenden Inhalt beim Aktualisieren des Snapshots
  expect(data).toMatchInlineSnapshot(`
    {
      "foo": Set {
        "bar",
        "snapshot",
      },
    }
  `);
});

Sie können auch eine Form eines Objekts angeben, wenn Sie nur die Form eines Objekts testen und es nicht zu 100% kompatibel sein muss:

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

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

toMatchFileSnapshot ​

  • Typ: <T>(filepath: string, hint?: 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('rendert grundlegend', 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 Dateisystemoperationen asynchron ablaufen. Wenn await nicht verwendet wird, interpretiert Vitest es wie expect.soft, was bedeutet, dass der Code nach der Anweisung weiter ausgeführt wird, selbst wenn der Snapshot nicht übereinstimmt. Nachdem der Test abgeschlossen ist, prüft Vitest den Snapshot und schlägt fehl, wenn eine Nichtübereinstimmung vorliegt.

toThrowErrorMatchingSnapshot ​

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

Dasselbe wie toMatchSnapshot, erwartet aber denselben Wert wie toThrowError.

toThrowErrorMatchingInlineSnapshot ​

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

Dasselbe wie toMatchInlineSnapshot, erwartet aber denselben Wert wie toThrowError.

toHaveBeenCalled ​

  • Typ: () => Awaitable<void>

Diese Assertion ist nützlich, um zu testen, ob eine Funktion aufgerufen wurde. Voraussetzung ist, dass eine Spy-Funktion an expect übergeben wird.

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

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

test('Spy-Funktion', () => {
  const buySpy = vi.spyOn(market, 'buy');

  expect(buySpy).not.toHaveBeenCalled();

  market.buy('Äpfel', 10);

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

toHaveBeenCalledTimes ​

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

Diese Assertion prüft, ob eine Funktion eine bestimmte Anzahl an Malen aufgerufen wurde. Voraussetzung ist, dass eine Spy-Funktion an expect übergeben wird.

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

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

test('Spy-Funktion zweimal aufgerufen', () => {
  const buySpy = vi.spyOn(market, 'buy');

  market.buy('Äpfel', 10);
  market.buy('Äpfel', 20);

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

toHaveBeenCalledWith ​

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

Diese Assertion prüft, ob eine Funktion mindestens einmal mit den angegebenen Parametern aufgerufen wurde. Voraussetzung ist, dass eine Spy-Funktion an expect übergeben wird.

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

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

test('Spy-Funktion', () => {
  const buySpy = vi.spyOn(market, 'buy');

  market.buy('Äpfel', 10);
  market.buy('Äpfel', 20);

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

toHaveBeenCalledBefore 3.0.0+ ​

  • Typ: (mock: MockInstance, failIfNoFirstInvocation?: boolean) => Awaitable<void>

Diese Assertion prüft, ob ein Mock vor einem anderen Mock aufgerufen wurde.

ts
test('ruft mock1 vor mock2 auf', () => {
  const mock1 = vi.fn();
  const mock2 = vi.fn();

  mock1();
  mock2();
  mock1();

  expect(mock1).toHaveBeenCalledBefore(mock2);
});

toHaveBeenCalledAfter 3.0.0+ ​

  • Typ: (mock: MockInstance, failIfNoFirstInvocation?: boolean) => Awaitable<void>

Diese Assertion prüft, ob ein Mock nach einem anderen Mock aufgerufen wurde.

ts
test('ruft mock1 nach mock2 auf', () => {
  const mock1 = vi.fn();
  const mock2 = vi.fn();

  mock2();
  mock1();
  mock2();

  expect(mock1).toHaveBeenCalledAfter(mock2);
});

toHaveBeenCalledExactlyOnceWith 3.0.0+ ​

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

Diese Assertion prüft, ob eine Funktion genau einmal und mit den angegebenen Parametern aufgerufen wurde. Voraussetzung ist, dass eine Spy-Funktion an expect übergeben wird.

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

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

test('Spy-Funktion', () => {
  const buySpy = vi.spyOn(market, 'buy');

  market.buy('Äpfel', 10);

  expect(buySpy).toHaveBeenCalledExactlyOnceWith('Äpfel', 10);
});

toHaveBeenLastCalledWith ​

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

Diese Assertion prüft, ob eine Funktion beim letzten Aufruf mit bestimmten Parametern aufgerufen wurde. Voraussetzung ist, dass eine Spy-Funktion an expect übergeben wird.

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

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

test('Spy-Funktion', () => {
  const buySpy = vi.spyOn(market, 'buy');

  market.buy('Äpfel', 10);
  market.buy('Äpfel', 20);

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

toHaveBeenNthCalledWith ​

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

Diese Assertion prüft, ob eine Funktion zu einem bestimmten Zeitpunkt mit bestimmten Parametern aufgerufen wurde. Die Zählung beginnt bei 1. Um den zweiten Eintrag zu prüfen, schreibt man also .toHaveBeenNthCalledWith(2, ...).

Voraussetzung ist, dass eine Spy-Funktion an expect übergeben wird.

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

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

test('erster Aufruf der Spy-Funktion mit den richtigen Parametern', () => {
  const buySpy = vi.spyOn(market, 'buy');

  market.buy('Äpfel', 10);
  market.buy('Äpfel', 20);

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

toHaveReturned ​

  • Typ: () => Awaitable<void>

Diese Assertion prüft, ob eine Funktion mindestens einmal erfolgreich einen Wert zurückgegeben hat (d.h. ohne einen Fehler auszulösen). Voraussetzung ist, dass eine Spy-Funktion an expect übergeben wird.

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

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

test('Spy-Funktion hat einen Wert zurückgegeben', () => {
  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 eine bestimmte Anzahl von Malen erfolgreich einen Wert zurückgegeben hat (d.h. ohne einen Fehler auszulösen). Voraussetzung ist, dass eine Spy-Funktion an expect übergeben wird.

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

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

  sell('Äpfel');
  sell('Bananen');

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

toHaveReturnedWith ​

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

Sie können diese Assertion aufrufen, um zu prüfen, ob eine Funktion mindestens einmal erfolgreich einen Wert mit den angegebenen Parametern zurückgegeben hat. Voraussetzung ist, dass eine Spy-Funktion an expect übergeben wird.

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

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

  sell('Äpfel');

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

toHaveLastReturnedWith ​

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

Sie können diese Assertion aufrufen, um zu prüfen, ob eine Funktion beim letzten Aufruf erfolgreich einen bestimmten Wert zurückgegeben hat. Voraussetzung ist, dass eine Spy-Funktion an expect übergeben wird.

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

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

  sell('Äpfel');
  sell('Bananen');

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

toHaveNthReturnedWith ​

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

Sie können diese Assertion aufrufen, um zu prüfen, ob eine Funktion bei einem spezifischen Aufruf erfolgreich einen Wert mit bestimmten Parametern zurückgegeben hat. Voraussetzung ist, dass eine Spy-Funktion an expect übergeben wird.

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

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

  sell('Äpfel');
  sell('Bananen');

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

toHaveResolved ​

  • Typ: () => Awaitable<void>

Diese Assertion prüft, ob eine Funktion mindestens einmal erfolgreich einen Wert aufgelöst hat (d.h. nicht abgelehnt wurde). Voraussetzung ist, dass eine Spy-Funktion an expect übergeben wird.

Wenn die Funktion ein Promise zurückgegeben hat, dieses aber noch nicht erfüllt wurde, schlägt dies fehl.

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

async function getApplesPrice(amount: number) {
  return amount * (await db.get('price'));
}

test('Spy-Funktion hat einen Wert aufgelöst', async () => {
  const getPriceSpy = vi.fn(getApplesPrice);

  const price = await getPriceSpy(10);

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

toHaveResolvedTimes ​

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

Diese Assertion prüft, ob eine Funktion genau eine bestimmte Anzahl von Malen erfolgreich einen Wert aufgelöst hat (d.h. nicht abgelehnt wurde). Voraussetzung ist, dass eine Spy-Funktion an expect übergeben wird.

Hierbei werden nur aufgelöste Promises gezählt. Wenn die Funktion ein Promise zurückgegeben hat, dieses aber noch nicht erfüllt wurde, wird es nicht gezählt.

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

test('Spy-Funktion hat zweimal einen Wert aufgelöst', async () => {
  const sell = vi.fn((product: string) => Promise.resolve({ product }));

  await sell('Äpfel');
  await sell('Bananen');

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

toHaveResolvedWith ​

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

Sie können diese Assertion aufrufen, um zu prüfen, ob eine Funktion mindestens einmal erfolgreich einen bestimmten Wert aufgelöst hat. Voraussetzung ist, dass eine Spy-Funktion an expect übergeben wird.

Wenn die Funktion ein Promise zurückgegeben hat, dieses aber noch nicht erfüllt wurde, schlägt dies fehl.

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

test('Spy-Funktion hat ein Produkt aufgelöst', async () => {
  const sell = vi.fn((product: string) => Promise.resolve({ product }));

  await sell('Äpfel');

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

toHaveLastResolvedWith ​

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

Sie können diese Assertion aufrufen, um zu prüfen, ob eine Funktion bei ihrem letzten Aufruf erfolgreich einen bestimmten Wert aufgelöst hat. Voraussetzung ist, dass eine Spy-Funktion an expect übergeben wird.

Wenn die Funktion ein Promise zurückgegeben hat, dieses aber noch nicht erfüllt wurde, schlägt dies fehl.

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

test('Spy-Funktion löst bei letztem Aufruf Bananen auf', async () => {
  const sell = vi.fn((product: string) => Promise.resolve({ product }));

  await sell('Äpfel');
  await sell('Bananen');

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

toHaveNthResolvedWith ​

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

Sie können diese Assertion aufrufen, um zu prüfen, ob eine Funktion bei einem spezifischen Aufruf erfolgreich einen bestimmten Wert aufgelöst hat. Voraussetzung ist, dass eine Spy-Funktion an expect übergeben wird.

Wenn die Funktion ein Promise zurückgegeben hat, dieses aber noch nicht erfüllt wurde, schlägt dies fehl.

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

test('Spy-Funktion gibt bei zweitem Aufruf Bananen zurück', async () => {
  const sell = vi.fn((product: string) => Promise.resolve({ product }));

  await sell('Äpfel');
  await sell('Bananen');

  expect(sell).toHaveNthResolvedWith(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';

const isOdd = (value: number) => value % 2 !== 0;

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

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

resolves ​

  • Typ: Promisify<Assertions>

resolves soll redundanten Code beim Bestätigen von asynchronem Code entfernen. Verwenden Sie es, um Werte aus dem ausstehenden Promise aufzulösen und ihren Wert mit den üblichen Assertions zu bestätigen. Wenn das Promise fehlschlägt, schlägt die Assertion fehl.

Es gibt dasselbe Assertions-Objekt zurück, aber alle Matcher geben jetzt Promise zurück, sodass Sie asynchron darauf warten müssen. Ist auch kompatibel mit chai-Assertions.

Wenn Sie beispielsweise eine Funktion haben, die einen API-Aufruf macht und Daten zurückgibt, können Sie diesen Code verwenden, um ihren Rückgabewert zu bestätigen:

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

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

test('buyApples gibt neue Bestands-ID zurück', async () => {
  // toEqual gibt jetzt ein Promise zurück, daher MÜSSEN Sie es awaiten
  await expect(buyApples()).resolves.toEqual({ id: 1 }); // jest API
  await expect(buyApples()).resolves.to.equal({ id: 1 }); // chai API
});

WARNING

Wenn die Assertion nicht asynchron abgewartet wird, erhalten Sie einen falsch-positiven Test, der jedes Mal besteht. Um sicherzustellen, dass Assertions wirklich aufgerufen werden, können Sie expect.assertions(number) verwenden.

Seit Vitest 3 zeigt Vitest am Ende des Tests eine Warnung an, wenn eine Methode nicht asynchron abgewartet wird. In Vitest 4 wird der Test als "fehlgeschlagen" markiert, wenn die Assertion nicht asynchron abgewartet wird.

rejects ​

  • Typ: Promisify<Assertions>

rejects soll redundanten Code beim Bestätigen von asynchronem Code entfernen. Verwenden Sie es, um den Ablehnungsgrund des Promises zu extrahieren und seinen Wert mit den üblichen Assertions zu bestätigen. Wenn das Promise erfolgreich erfüllt wird, schlägt die Assertion fehl.

Es gibt dasselbe Assertions-Objekt zurück, aber alle Matcher geben jetzt Promise zurück, sodass Sie asynchron darauf warten müssen. Ist auch kompatibel 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 bestätigen:

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

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

test('buyApples wirft einen Fehler, wenn keine ID angegeben wird', async () => {
  // toThrow gibt jetzt ein Promise zurück, daher MÜSSEN Sie es awaiten
  await expect(buyApples()).rejects.toThrow('keine ID');
});

WARNING

Wenn die Assertion nicht asynchron abgewartet wird, erhalten Sie einen falsch-positiven Test, der jedes Mal besteht. Um sicherzustellen, dass Assertions wirklich aufgerufen wurden, können Sie expect.assertions(number) verwenden.

Seit Vitest 3 zeigt Vitest am Ende des Tests eine Warnung an, wenn eine Methode nicht asynchron abgewartet wird. In Vitest 4 wird der Test als "fehlgeschlagen" markiert, wenn die Assertion nicht asynchron abgewartet wird.

expect.assertions ​

  • Typ: (count: number) => void

Nachdem der Test bestanden oder fehlgeschlagen ist, wird überprüft, ob eine bestimmte Anzahl von Assertions während eines Tests aufgerufen wurde. Ein nützlicher Anwendungsfall ist es, zu prüfen, ob ein asynchroner Code aufgerufen wurde.

Wenn wir beispielsweise eine Funktion haben, die asynchron zwei Matcher aufruft, können wir bestätigen, dass sie tatsächlich aufgerufen wurden.

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

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

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

  await doAsync(callback1, callback2);
});

WARNING

Bei der Verwendung von assertions mit asynchronen, parallelen Tests muss expect aus dem lokalen Testkontext verwendet werden, um sicherzustellen, dass der korrekte Test identifiziert wird.

expect.hasAssertions ​

  • Typ: () => void

Nachdem der Test bestanden oder fehlgeschlagen ist, wird überprüft, ob mindestens eine Assertion während eines Tests aufgerufen wurde. Ein nützlicher Anwendungsfall ist es, zu prüfen, ob ein asynchroner Code aufgerufen wurde.

Wenn Sie beispielsweise einen Code haben, der einen Callback aufruft, können wir eine Assertion innerhalb eines Callbacks machen, aber der Test wird immer bestanden, wenn wir nicht prüfen, ob eine Assertion aufgerufen wurde.

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

const cbs = [];

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

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

test('Callback wurde aufgerufen', async () => {
  expect.hasAssertions();
  onSelect(data => {
    // sollte bei Auswahl aufgerufen werden
    expect(data).toBeTruthy();
  });
  // wenn nicht asynchron abgewartet, schlägt der Test fehl
  // wenn expect.hasAssertions() nicht verwendet wird, besteht der Test
  await select(3);
});

expect.unreachable ​

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

Diese Methode wird verwendet, um sicherzustellen, dass eine bestimmte Codezeile niemals erreicht wird.

Wenn wir zum Beispiel testen möchten, dass build() einen Fehler wirft, weil die Zielverzeichnisse keinen src-Ordner enthalten, und jeden Fehler separat behandeln möchten, könnten wir dies tun:

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

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

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

test.each(errorDirs)('Build schlägt fehl mit "%s"', async dir => {
  try {
    await build(dir);
    expect.unreachable('Sollte den Build 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 existiert nicht`);
        break;
      default:
        // um alle Fehlertests zu erschöpfen
        expect.unreachable('Alle Fehlertests müssen behandelt werden');
        break;
    }
  }
});

expect.anything ​

  • Typ: () => any

Dieser asymmetrische Matcher gibt in Verbindung mit einem Gleichheitscheck 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 in Verbindung mit einem Gleichheitscheck 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 einen geeigneten Typ hat.

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 ​

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

expect.closeTo ist nützlich beim Vergleichen von Gleitkommazahlen in Objekteigenschaften oder Array-Elementen. Wenn Sie eine Zahl vergleichen müssen, verwenden Sie stattdessen .toBeCloseTo.

Das optionale precision-Argument begrenzt die Anzahl der zu berücksichtigenden Nachkommastellen. Für den Standardwert 2 gilt das Testkriterium Math.abs(expected - received) < 0.005 (d.h. 10 ** -2 / 2).

Zum Beispiel besteht dieser Test mit einer Genauigkeit von 5 Ziffern:

js
test('Gleitkommazahlen in Objekteigenschaften vergleichen', () => {
  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

In Verbindung mit einem Gleichheitscheck 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('Korb enthält Fuji', () => {
  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

In Verbindung mit einem Gleichheitscheck gibt dieser asymmetrische Matcher true zurück, wenn der Wert eine ähnliche Form hat.

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

test('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

In Verbindung mit einem Gleichheitscheck gibt dieser asymmetrische Matcher true zurück, wenn der Wert ein String ist und einen angegebenen Substring enthält.

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

test('Sorte 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

In Verbindung mit einem Gleichheitscheck gibt dieser asymmetrische Matcher true zurück, wenn der Wert ein String ist und einen angegebenen Substring enthält oder wenn der String einem regulären Ausdruck entspricht.

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

test('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 Serializer hinzu, die beim Erstellen eines Snapshots zum Einsatz kommen. Dies ist eine fortgeschrittene Funktion – weitere Informationen finden Sie im Leitfaden zu benutzerdefinierten Serializern.

Wenn Sie benutzerdefinierte Serializer hinzufügen, ist es ratsam, diese Methode innerhalb von setupFiles aufzurufen. Dies betrifft jeden Snapshot.

TIP

Wenn Sie zuvor Vue CLI mit Jest verwendet haben, möchten Sie möglicherweise jest-serializer-vue installieren. Andernfalls werden Ihre Snapshots in einen String gewickelt, wodurch " maskiert wird.

expect.extend ​

  • Typ: (matchers: MatchersObject) => void

Sie können Standard-Matcher um eigene Matcher erweitern. Diese Funktion wird verwendet, um das Matcher-Objekt um benutzerdefinierte Matcher zu erweitern.

Wenn Sie Matcher so 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} 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, ist es ratsam, diese Methode innerhalb von setupFiles aufzurufen.

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

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 einzubinden.

TIP

Wenn Sie mehr wissen möchten, schauen Sie sich den Leitfaden zum Erweitern von Matchern an.

expect.addEqualityTesters ​

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

Sie können diese Methode verwenden, um benutzerdefinierte Tester zu definieren, die von Matchern eingesetzt werden, um zu prüfen, ob zwei Objekte gleich sind. Sie ist kompatibel mit Jests expect.addEqualityTesters.

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 = isAnagramComparator(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) 2021-Present Vitest Team

https://vitest.dev/api/expect

Veröffentlicht unter der MIT-Lizenz.

Copyright (c) 2021-Present Vitest Team