Skip to content
Vitest 3
Main Navigation Przewodnik & APIKonfiguracjaTryb przeglądarkiZaawansowane API
3.2.0
2.1.9
1.6.1
0.34.6

Polski

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

Polski

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

Wygląd

Sidebar Navigation

Wprowadzenie

Dlaczego Vitest

Pierwsze kroki

Funkcje

Konfiguracja Vitest

API

Dokumentacja API testowego

Funkcje Mock

Vi

expect

expectTypeOf

assert

assertType

Przewodnik

Interfejs Wiersza Poleceń

Filtrowanie testów

Projekty testowe

Reportery

Pokrycie kodu

Migawki

Mockowanie

Równoległość

Typy testów

Interfejs użytkownika Vitest

Testy w kodzie źródłowym

Kontekst Testu

Adnotacje testowe

Środowisko testowe

Rozszerzanie matcherów

Integracje z IDE

Debugowanie

Typowe błędy

Przewodnik migracji

Migracja do Vitest 3.0

Migracja z Jest

Wydajność

Profilowanie wydajności testów

Poprawa wydajności

Tryb przeglądarkowy

Zaawansowane API

Porównania z innymi narzędziami do uruchamiania testów

Na tej stronie

expect ​

Poniższe typy są używane w poniższych sygnaturach typów.

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

expect służy do tworzenia asercji. W tym kontekście asercje to funkcje, które można wywołać, aby potwierdzić dane stwierdzenie. Vitest domyślnie dostarcza asercje chai, a także asercje kompatybilne z Jest, zbudowane na bazie chai. W przeciwieństwie do Jest, Vitest obsługuje wiadomość jako drugi argument – jeśli asercja zakończy się niepowodzeniem, komunikat błędu będzie równy temu.

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;
}

Na przykład, ten kod potwierdza, że wartość input wynosi 2. Jeśli nie jest, asercja zgłosi błąd, a test zakończy się niepowodzeniem.

ts
import { expect } from 'vitest';

const input = Math.sqrt(4);

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

Technicznie ten przykład nie używa funkcji test, więc w konsoli zobaczysz błąd Node.js zamiast wyników Vitest. Aby dowiedzieć się więcej o test, przeczytaj Test API Reference.

Ponadto, expect może być używany statycznie do dostępu do funkcji dopasowujących, opisanych później, oraz innych funkcji.

WARNING

expect nie wpływa na testowanie typów, jeśli wyrażenie nie generuje błędu typu. Jeśli chcesz używać Vitest jako sprawdzania typów, użyj expectTypeOf lub assertType.

soft ​

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

expect.soft działa podobnie do expect, ale zamiast przerywać wykonanie testu po nieudanej asercji, kontynuuje działanie i oznacza niepowodzenie jako błąd testu. Wszystkie błędy napotkane podczas testu zostaną wyświetlone do momentu zakończenia testu.

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

test('expect.soft test', () => {
  expect.soft(1 + 1).toBe(3); // oznacza test jako nieudany i kontynuuje
  expect.soft(1 + 2).toBe(4); // oznacza test jako nieudany i kontynuuje
});
// reporter zgłosi oba błędy na koniec uruchomienia

Może być również używany z expect. Jeśli asercja expect zakończy się niepowodzeniem, test zostanie przerwany, a wszystkie błędy zostaną wyświetlone.

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

test('expect.soft test', () => {
  expect.soft(1 + 1).toBe(3); // oznacza test jako nieudany i kontynuuje
  expect(1 + 2).toBe(4); // niepowodzenie i zakończenie testu; wszystkie poprzednie błędy zostaną wyświetlone
  expect.soft(1 + 3).toBe(5); // nie uruchamiaj
});

WARNING

expect.soft może być używany tylko wewnątrz funkcji test.

poll ​

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

expect.poll ponownie uruchamia asercję, dopóki nie zakończy się ona sukcesem. Możesz skonfigurować, ile razy Vitest powinien ponownie uruchomić callback expect.poll, ustawiając opcje interval i timeout.

Jeśli wewnątrz callbacku expect.poll zostanie zgłoszony błąd, Vitest spróbuje ponownie, aż upłynie limit czasu.

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

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

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

WARNING

expect.poll sprawia, że każda asercja jest asynchroniczna, więc musisz ją awaitować. Od Vitest 3, jeśli zapomnisz ją awaitować, test zakończy się niepowodzeniem z ostrzeżeniem, aby to zrobić.

expect.poll nie działa z kilkoma dopasowaniami:

  • Dopasowania migawek nie są obsługiwane, ponieważ zawsze zwrócą sukces. Jeśli twój warunek jest niestabilny, rozważ użycie vi.waitFor zamiast tego, aby najpierw go rozwiązać:
ts
import { expect, vi } from 'vitest';

const flakyValue = await vi.waitFor(() => getFlakyValue());
expect(flakyValue).toMatchSnapshot();
  • .resolves i .rejects nie są obsługiwane. expect.poll już oczekuje na warunek, jeśli jest asynchroniczny.
  • toThrow i jego aliasy nie są obsługiwane, ponieważ warunek expect.poll jest zawsze rozstrzygany, zanim dopasowanie otrzyma wartość

not ​

Użycie not zaneguje asercję. Na przykład, ten kod potwierdza, że wartość input nie jest równa 2. Jeśli jest równa, asercja zgłosi błąd, a test zakończy się niepowodzeniem.

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 może być używany do potwierdzania równości prymitywów lub tego, że obiekty współdzielą tę samą referencję. Jest to równoważne wywołaniu expect(Object.is(3, 3)).toBe(true). Jeśli obiekty nie są takie same, ale chcesz sprawdzić, czy ich struktury są identyczne, możesz użyć toEqual.

Na przykład, poniższy kod sprawdza, czy handlowiec ma 13 jabłek.

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

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

test('stock ma 13 jabłek', () => {
  expect(stock.type).toBe('apples');
  expect(stock.count).toBe(13);
});

test('zapasy są takie same', () => {
  const refStock = stock; // ta sama referencja

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

Staraj się nie używać toBe z liczbami zmiennoprzecinkowymi. Ponieważ JavaScript zaokrągla je, 0.1 + 0.2 nie jest dokładnie 0.3. Aby wiarygodnie potwierdzić liczby zmiennoprzecinkowe, użyj asercji toBeCloseTo.

toBeCloseTo ​

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

Użyj toBeCloseTo do porównywania liczb zmiennoprzecinkowych. Opcjonalny argument numDigits ogranicza liczbę cyfr do sprawdzenia po przecinku. Na przykład:

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

test.fails('liczby zmiennoprzecinkowe nie są równe w JavaScript', () => {
  expect(0.2 + 0.1).toBe(0.3); // 0.2 + 0.1 to 0.30000000000000004
});

test('liczby zmiennoprzecinkowe są zaokrąglane do 5 miejsc po przecinku', () => {
  // 0.2 + 0.1 to 0.30000 | "000000000004" usunięte
  expect(0.2 + 0.1).toBeCloseTo(0.3, 5);
  // nic z 0.30000000000000004 nie jest usunięte
  expect(0.2 + 0.1).not.toBeCloseTo(0.3, 50);
});

toBeDefined ​

  • Typ: () => Awaitable<void>

toBeDefined potwierdza, że wartość nie jest równa undefined. Przydatnym przypadkiem użycia byłoby sprawdzenie, czy funkcja zwróciła jakąś wartość.

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

function getApples() {
  return 3;
}

test('funkcja coś zwróciła', () => {
  expect(getApples()).toBeDefined();
});

toBeUndefined ​

  • Typ: () => Awaitable<void>

Przeciwieństwo toBeDefined, toBeUndefined potwierdza, że wartość jest równa undefined. Przydatnym przypadkiem użycia byłoby sprawdzenie, czy funkcja nie zwróciła żadnej wartości.

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

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

test("Mary nie ma jabłek w magazynie", () => {
  expect(getApplesFromStock('Mary')).toBeUndefined();
});

toBeTruthy ​

  • Typ: () => Awaitable<void>

toBeTruthy potwierdza, że wartość jest prawdziwa po konwersji na boolean. Przydatne, jeśli nie zależy ci na wartości, ale chcesz wiedzieć, czy można ją przekonwertować na true.

Na przykład, mając ten kod, nie zależy ci na wartości zwracanej przez stocks.getInfo - może to być złożony obiekt, ciąg znaków lub cokolwiek innego. Kod nadal będzie działać.

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

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

Więc jeśli chcesz przetestować, czy stocks.getInfo będzie prawdziwe, możesz napisać:

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

const stocks = new Stocks();

test('jeśli znamy zapasy Billa, sprzedaj mu jabłka', () => {
  stocks.sync('Bill');
  expect(stocks.getInfo('Bill')).toBeTruthy();
});

Wszystko w JavaScript jest prawdziwe, z wyjątkiem false, null, undefined, NaN, 0, -0, 0n, "" i document.all.

toBeFalsy ​

  • Typ: () => Awaitable<void>

toBeFalsy potwierdza, że wartość jest fałszywa po konwersji na boolean. Przydatne, jeśli nie zależy ci na wartości, ale chcesz wiedzieć, czy można ją przekonwertować na false.

Na przykład, mając ten kod, nie zależy ci na wartości zwracanej przez stocks.stockFailed - może zwrócić dowolną fałszywą wartość, ale kod nadal będzie działać.

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

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

Więc jeśli chcesz przetestować, czy stocks.stockFailed będzie fałszywe, możesz napisać:

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

const stocks = new Stocks();

test("jeśli zapasy Billa nie okazały się wadliwe, sprzedaj mu jabłka", () => {
  stocks.syncStocks('Bill');
  expect(stocks.stockFailed('Bill')).toBeFalsy();
});

Wszystko w JavaScript jest prawdziwe, z wyjątkiem false, null, undefined, NaN, 0, -0, 0n, "" i document.all.

toBeNull ​

  • Typ: () => Awaitable<void>

toBeNull po prostu potwierdza, czy coś jest null. Alias dla .toBe(null).

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

function apples() {
  return null;
}

test("nie mamy jabłek", () => {
  expect(apples()).toBeNull();
});

toBeNaN ​

  • Typ: () => Awaitable<void>

toBeNaN po prostu potwierdza, czy coś jest NaN. Alias dla .toBe(NaN).

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

let i = 0;

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

test('getApplesCount ma pewne nietypowe efekty uboczne...', () => {
  expect(getApplesCount()).not.toBeNaN();
  expect(getApplesCount()).toBeNaN();
});

toBeOneOf ​

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

toBeOneOf potwierdza, czy wartość pasuje do którejkolwiek z wartości w dostarczonej tablicy.

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

test('owoc jest jedną z dozwolonych wartości', () => {
  expect(fruit).toBeOneOf(['jabłko', 'banan', 'pomarańcza']);
});

Asymetryczny dopasowywacz jest szczególnie przydatny podczas testowania opcjonalnych właściwości, które mogą być null lub undefined:

ts
test('opcjonalne właściwości mogą być null lub undefined', () => {
  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

Możesz użyć expect.not z tym dopasowywaczem, aby upewnić się, że wartość NIE pasuje do żadnej z podanych opcji.

toBeTypeOf ​

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

toBeTypeOf potwierdza, czy rzeczywista wartość jest typu otrzymanego typu.

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

const actual = 'stock';

test('stock jest typu string', () => {
  expect(actual).toBeTypeOf('string');
});

toBeInstanceOf ​

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

toBeInstanceOf potwierdza, czy rzeczywista wartość jest instancją otrzymanej klasy.

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

const stocks = new Stocks();

test('stocks są instancją Stocks', () => {
  expect(stocks).toBeInstanceOf(Stocks);
});

toBeGreaterThan ​

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

toBeGreaterThan potwierdza, czy rzeczywista wartość jest większa niż otrzymana. Równe wartości spowodują niepowodzenie testu.

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

test('ma więcej niż 10 jabłek', () => {
  expect(getApples()).toBeGreaterThan(10);
});

toBeGreaterThanOrEqual ​

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

toBeGreaterThanOrEqual potwierdza, czy rzeczywista wartość jest większa niż otrzymana lub jej równa.

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

test('ma 11 jabłek lub więcej', () => {
  expect(getApples()).toBeGreaterThanOrEqual(11);
});

toBeLessThan ​

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

toBeLessThan potwierdza, czy rzeczywista wartość jest mniejsza niż otrzymana. Równe wartości spowodują niepowodzenie testu.

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

test('ma mniej niż 20 jabłek', () => {
  expect(getApples()).toBeLessThan(20);
});

toBeLessThanOrEqual ​

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

toBeLessThanOrEqual potwierdza, czy rzeczywista wartość jest mniejsza niż otrzymana lub jej równa.

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

test('ma 11 jabłek lub mniej', () => {
  expect(getApples()).toBeLessThanOrEqual(11);
});

toEqual ​

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

toEqual potwierdza, czy rzeczywista wartość jest równa otrzymanej lub ma taką samą strukturę, jeśli jest obiektem (porównuje je rekurencyjnie). Różnicę między toEqual a toBe można zobaczyć w tym przykładzie:

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

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

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

test('zapasy mają te same właściwości', () => {
  expect(stockBill).toEqual(stockMary);
});

test('zapasy nie są takie same', () => {
  expect(stockBill).not.toBe(stockMary);
});

WARNING

Dla obiektów Error, porównywane są również właściwości niewyliczalne, takie jak name, message, cause i AggregateError.errors. Dla Error.cause porównanie odbywa się asymetrycznie:

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

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

Aby sprawdzić, czy coś zostało rzucone, użyj asercji toThrowError.

toStrictEqual ​

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

toStrictEqual potwierdza, czy rzeczywista wartość jest równa otrzymanej lub ma taką samą strukturę, jeśli jest obiektem (porównuje je rekurencyjnie), i tego samego typu.

Różnice w stosunku do .toEqual:

  • Sprawdzane są klucze z właściwościami undefined. np. {a: undefined, b: 2} nie pasuje do {b: 2} przy użyciu .toStrictEqual.
  • Sprawdzana jest rzadkość występowania elementów w tablicy. np. [, 1] nie pasuje do [undefined, 1] przy użyciu .toStrictEqual.
  • Typy obiektów są sprawdzane pod kątem równości. np. Instancja klasy z polami a i b nie będzie równa obiektowi literalnemu z polami a i b.
ts
import { expect, test } from 'vitest';

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

test('strukturalnie takie same, ale semantycznie różne', () => {
  expect(new Stock('apples')).toEqual({ type: 'apples' });
  expect(new Stock('apples')).not.toStrictEqual({ type: 'apples' });
});

toContain ​

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

toContain potwierdza, czy rzeczywista wartość znajduje się w tablicy. toContain może również sprawdzić, czy ciąg znaków jest podciągiem innego ciągu znaków. Jeśli uruchamiasz testy w środowisku podobnym do przeglądarki, ta asercja może również sprawdzić, czy klasa jest zawarta w classList, lub czy element znajduje się w innym elemencie.

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

test('lista owoców zawiera pomarańczę', () => {
  expect(getAllFruits()).toContain('orange');

  const element = document.querySelector('#el');
  // element ma klasę
  expect(element.classList).toContain('flex');
  // element znajduje się w innym
  expect(document.querySelector('#wrapper')).toContain(element);
});

toContainEqual ​

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

toContainEqual potwierdza, czy element o określonej strukturze i wartościach jest zawarty w tablicy. Działa jak toEqual wewnątrz dla każdego elementu.

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

test('jabłko dostępne', () => {
  expect(getFruitStock()).toContainEqual({ fruit: 'apple', count: 5 });
});

toHaveLength ​

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

toHaveLength potwierdza, czy obiekt ma właściwość .length i czy jest ona ustawiona na określoną wartość liczbową.

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

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

  expect('').not.toHaveLength(3); // nie ma długości równej 3
  expect({ length: 3 }).toHaveLength(3);
});

toHaveProperty ​

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

toHaveProperty potwierdza, czy właściwość pod podanym kluczem key istnieje dla obiektu.

Możesz podać opcjonalny argument wartości, znany również jako głęboka równość, podobnie jak dopasowywacz toEqual, aby porównać otrzymaną wartość właściwości.

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('Faktura Johna Doe', () => {
  expect(invoice).toHaveProperty('isActive'); // potwierdź, że klucz istnieje
  expect(invoice).toHaveProperty('total_amount', 5000); // potwierdź, że klucz istnieje i wartość jest równa

  expect(invoice).not.toHaveProperty('account'); // potwierdź, że ten klucz nie istnieje

  // Odwoływanie się do zagnieżdżonych właściwości za pomocą notacji kropkowej
  expect(invoice).toHaveProperty('customer.first_name');
  expect(invoice).toHaveProperty('customer.last_name', 'Doe');
  expect(invoice).not.toHaveProperty('customer.location', 'India');

  // Odwoływanie się do zagnieżdżonych właściwości za pomocą tablicy zawierającej klucz
  expect(invoice).toHaveProperty('items[0].type', 'apples');
  expect(invoice).toHaveProperty('items.0.type', 'apples'); // notacja kropkowa również działa

  // Odwoływanie się do zagnieżdżonych właściwości za pomocą tablicy zawierającej ścieżkę klucza
  expect(invoice).toHaveProperty(['items', 0, 'type'], 'apples');
  expect(invoice).toHaveProperty(['items', '0', 'type'], 'apples'); // notacja stringowa również działa

  // Zawiń klucz w tablicę, aby uniknąć interpretowania go jako zagnieżdżonego odwołania
  expect(invoice).toHaveProperty(['P.O'], '12345');
});

toMatch ​

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

toMatch potwierdza, czy ciąg znaków pasuje do wyrażenia regularnego lub ciągu znaków.

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

test('najlepsze owoce', () => {
  expect('najlepsze owoce to jabłko, pomarańcza i winogrono').toMatch(/jabłko/);
  expect('jabłkoowoce').toMatch('owoc'); // toMatch akceptuje również ciąg znaków
});

toMatchObject ​

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

toMatchObject potwierdza, czy obiekt pasuje do podzbioru właściwości obiektu.

Możesz również przekazać tablicę obiektów. Jest to przydatne, jeśli chcesz sprawdzić, czy dwie tablice pasują do siebie pod względem liczby elementów, w przeciwieństwie do arrayContaining, który pozwala na dodatkowe elementy w otrzymanej tablicy.

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('faktura zawiera dane osobowe Johna', () => {
  expect(johnInvoice).toMatchObject(johnDetails);
});

test('liczba elementów musi się dokładnie zgadzać', () => {
  // Potwierdź, że tablica obiektów pasuje
  expect([{ foo: 'bar' }, { baz: 1 }]).toMatchObject([
    { foo: 'bar' },
    { baz: 1 },
  ]);
});

toThrowError ​

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

  • Alias: toThrow

toThrowError potwierdza, czy funkcja zgłasza błąd po jej wywołaniu.

Możesz podać opcjonalny argument, aby przetestować, czy zgłoszony jest konkretny błąd:

  • RegExp: komunikat błędu pasuje do wzorca
  • string: komunikat błędu zawiera podciąg
  • Error, AsymmetricMatcher: porównaj z otrzymanym obiektem podobnie do toEqual(received)

TIP

Musisz zawinąć kod w funkcję, w przeciwnym razie błąd nie zostanie przechwycony, a test zakończy się niepowodzeniem.

Nie dotyczy to wywołań asynchronicznych, ponieważ rejects poprawnie rozwija obietnicę:

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

Na przykład, jeśli chcemy przetestować, czy getFruitStock('pineapples') rzuca błąd, możemy napisać:

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

function getFruitStock(type: string) {
  if (type === 'pineapples') {
    throw new Error('Ananasy nie są dostępne w magazynie');
  }

  // Wykonaj inne czynności
}

test('rzuca błąd na ananasach', () => {
  // Sprawdź, czy komunikat błędu zawiera gdzieś słowo "stock": są to równoważne
  expect(() => getFruitStock('pineapples')).toThrowError(/stock/);
  expect(() => getFruitStock('pineapples')).toThrowError('stock');

  // Sprawdź dokładny komunikat błędu
  expect(() => getFruitStock('pineapples')).toThrowError(
    /^Ananasy nie są dostępne w magazynie$/
  );

  expect(() => getFruitStock('pineapples')).toThrowError(
    new Error('Ananasy nie są dostępne w magazynie')
  );
  expect(() => getFruitStock('pineapples')).toThrowError(
    expect.objectContaining({
      message: 'Ananasy nie są dostępne w magazynie',
    })
  );
});

TIP

Aby przetestować funkcje asynchroniczne, użyj w połączeniu z rejects.

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

test('rzuca błąd na ananasach', async () => {
  await expect(() => getAsyncFruitStock()).rejects.toThrowError('empty');
});

toMatchSnapshot ​

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

To zapewnia, że wartość pasuje do najnowszej migawki.

Możesz podać opcjonalny argument hint (wskazówka) w postaci ciągu znaków, który zostanie dołączony do nazwy testu. Chociaż Vitest zawsze dodaje liczbę na końcu nazwy migawki, krótkie, opisowe wskazówki mogą być bardziej przydatne niż liczby do rozróżniania wielu migawek w pojedynczym bloku it lub test. Vitest sortuje migawki według nazwy w odpowiednim pliku .snap.

TIP

Gdy migawka nie pasuje i powoduje niepowodzenie testu, jeśli niezgodność jest oczekiwana, możesz nacisnąć klawisz u, aby jednorazowo zaktualizować migawkę. Możesz też przekazać opcje CLI -u lub --update, aby Vitest zawsze aktualizował testy.

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

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

Możesz również podać kształt obiektu, jeśli testujesz tylko kształt obiektu i nie potrzebujesz, aby był w 100% kompatybilny:

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

test('pasuje do migawki', () => {
  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

To zapewnia, że wartość pasuje do najnowszej migawki.

Vitest dodaje i aktualizuje argument ciągu znaków inlineSnapshot do dopasowywacza w pliku testowym (zamiast zewnętrznego pliku .snap).

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

test('pasuje do migawki inline', () => {
  const data = { foo: new Set(['bar', 'snapshot']) };
  // Vitest zaktualizuje następującą zawartość podczas aktualizacji migawki
  expect(data).toMatchInlineSnapshot(`
    {
      "foo": Set {
        "bar",
        "snapshot",
      },
    }
  `);
});

Możesz również podać kształt obiektu, jeśli testujesz tylko kształt obiektu i nie potrzebujesz, aby był w 100% kompatybilny:

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

test('pasuje do migawki', () => {
  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>

Porównaj lub zaktualizuj migawkę z zawartością pliku jawnie określonego (zamiast pliku .snap).

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

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

Zauważ, że ponieważ operacja na systemie plików jest asynchroniczna, musisz użyć await z toMatchFileSnapshot(). Jeśli await nie zostanie użyte, Vitest traktuje to jak expect.soft, co oznacza, że kod po instrukcji będzie kontynuował działanie, nawet jeśli migawka nie pasuje. Po zakończeniu testu Vitest sprawdzi migawkę i zakończy się niepowodzeniem, jeśli wystąpi niezgodność.

toThrowErrorMatchingSnapshot ​

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

To samo co toMatchSnapshot, ale oczekuje tej samej wartości co toThrowError.

toThrowErrorMatchingInlineSnapshot ​

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

To samo co toMatchInlineSnapshot, ale oczekuje tej samej wartości co toThrowError.

toHaveBeenCalled ​

  • Typ: () => Awaitable<void>

Ta asercja jest przydatna do sprawdzania, czy funkcja została wywołana. Wymaga przekazania funkcji szpiegującej do expect.

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

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

test('funkcja szpiegująca', () => {
  const buySpy = vi.spyOn(market, 'buy');

  expect(buySpy).not.toHaveBeenCalled();

  market.buy('jabłka', 10);

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

toHaveBeenCalledTimes ​

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

Ta asercja sprawdza, czy funkcja została wywołana określoną liczbę razy. Wymaga przekazania funkcji szpiegującej do expect.

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

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

test('funkcja szpiegująca wywołana dwa razy', () => {
  const buySpy = vi.spyOn(market, 'buy');

  market.buy('jabłka', 10);
  market.buy('jabłka', 20);

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

toHaveBeenCalledWith ​

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

Ta asercja sprawdza, czy funkcja została wywołana co najmniej raz z określonymi parametrami. Wymaga przekazania funkcji szpiegującej do expect.

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

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

test('funkcja szpiegująca', () => {
  const buySpy = vi.spyOn(market, 'buy');

  market.buy('jabłka', 10);
  market.buy('jabłka', 20);

  expect(buySpy).toHaveBeenCalledWith('jabłka', 10);
  expect(buySpy).toHaveBeenCalledWith('jabłka', 20);
});

toHaveBeenCalledBefore 3.0.0+ ​

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

Ta asercja sprawdza, czy Mock został wywołany przed innym Mock.

ts
test('wywołuje mock1 przed mock2', () => {
  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>

Ta asercja sprawdza, czy Mock został wywołany po innym Mock.

ts
test('wywołuje mock1 po mock2', () => {
  const mock1 = vi.fn();
  const mock2 = vi.fn();

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

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

toHaveBeenCalledExactlyOnceWith 3.0.0+ ​

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

Ta asercja sprawdza, czy funkcja została wywołana dokładnie raz i z określonymi parametrami. Wymaga przekazania funkcji szpiegującej do expect.

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

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

test('funkcja szpiegująca', () => {
  const buySpy = vi.spyOn(market, 'buy');

  market.buy('jabłka', 10);

  expect(buySpy).toHaveBeenCalledExactlyOnceWith('jabłka', 10);
});

toHaveBeenLastCalledWith ​

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

Ta asercja sprawdza, czy funkcja została wywołana z określonymi parametrami podczas jej ostatniego wywołania. Wymaga przekazania funkcji szpiegującej do expect.

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

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

test('funkcja szpiegująca', () => {
  const buySpy = vi.spyOn(market, 'buy');

  market.buy('jabłka', 10);
  market.buy('jabłka', 20);

  expect(buySpy).not.toHaveBeenLastCalledWith('jabłka', 10);
  expect(buySpy).toHaveBeenLastCalledWith('jabłka', 20);
});

toHaveBeenNthCalledWith ​

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

Ta asercja sprawdza, czy funkcja została wywołana z określonymi parametrami w określonym czasie. Licznik zaczyna się od 1. Aby sprawdzić drugie wywołanie, należy napisać .toHaveBeenNthCalledWith(2, ...).

Wymaga przekazania funkcji szpiegującej do expect.

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

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

test('pierwsze wywołanie funkcji szpiegującej z prawidłowymi parametrami', () => {
  const buySpy = vi.spyOn(market, 'buy');

  market.buy('jabłka', 10);
  market.buy('jabłka', 20);

  expect(buySpy).toHaveBeenNthCalledWith(1, 'jabłka', 10);
});

toHaveReturned ​

  • Typ: () => Awaitable<void>

Ta asercja sprawdza, czy funkcja pomyślnie zwróciła wartość co najmniej raz (tj. nie zgłosiła błędu). Wymaga przekazania funkcji szpiegującej do expect.

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

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

test('funkcja szpiegująca zwróciła wartość', () => {
  const getPriceSpy = vi.fn(getApplesPrice);

  const price = getPriceSpy(10);

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

toHaveReturnedTimes ​

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

Ta asercja sprawdza, czy funkcja pomyślnie zwróciła wartość dokładnie określoną liczbę razy (tj. nie zgłosiła błędu). Wymaga przekazania funkcji szpiegującej do expect.

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

test('funkcja szpiegująca zwraca wartość dwa razy', () => {
  const sell = vi.fn((product: string) => ({ product }));

  sell('jabłka');
  sell('banany');

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

toHaveReturnedWith ​

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

Możesz wywołać tę asercję, aby sprawdzić, czy funkcja pomyślnie zwróciła wartość z określonymi parametrami co najmniej raz. Wymaga przekazania funkcji szpiegującej do expect.

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

test('funkcja szpiegująca zwraca produkt', () => {
  const sell = vi.fn((product: string) => ({ product }));

  sell('jabłka');

  expect(sell).toHaveReturnedWith({ product: 'jabłka' });
});

toHaveLastReturnedWith ​

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

Możesz wywołać tę asercję, aby sprawdzić, czy funkcja pomyślnie zwróciła określoną wartość podczas ostatniego wywołania. Wymaga przekazania funkcji szpiegującej do expect.

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

test('funkcja szpiegująca zwraca banany przy ostatnim wywołaniu', () => {
  const sell = vi.fn((product: string) => ({ product }));

  sell('jabłka');
  sell('banany');

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

toHaveNthReturnedWith ​

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

Możesz wywołać tę asercję, aby sprawdzić, czy funkcja pomyślnie zwróciła wartość z określonymi parametrami w określonym wywołaniu. Wymaga przekazania funkcji szpiegującej do expect.

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

test('funkcja szpiegująca zwraca banany przy drugim wywołaniu', () => {
  const sell = vi.fn((product: string) => ({ product }));

  sell('jabłka');
  sell('banany');

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

toHaveResolved ​

  • Typ: () => Awaitable<void>

Ta asercja sprawdza, czy funkcja pomyślnie rozwiązała wartość co najmniej raz (tj. nie odrzuciła). Wymaga przekazania funkcji szpiegującej do expect.

Jeśli funkcja zwróciła obietnicę, ale nie została ona jeszcze rozwiązana, to zakończy się niepowodzeniem.

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('funkcja szpiegująca rozwiązała wartość', async () => {
  const getPriceSpy = vi.fn(getApplesPrice);

  const price = await getPriceSpy(10);

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

toHaveResolvedTimes ​

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

Ta asercja sprawdza, czy funkcja pomyślnie rozwiązała wartość dokładnie określoną liczbę razy (tj. nie odrzuciła). Wymaga przekazania funkcji szpiegującej do expect.

To zliczy tylko rozwiązane obietnice. Jeśli funkcja zwróciła obietnicę, ale nie została ona jeszcze rozwiązana, nie zostanie ona zliczona.

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

test('funkcja szpiegująca rozwiązała wartość dwa razy', async () => {
  const sell = vi.fn((product: string) => Promise.resolve({ product }));

  await sell('jabłka');
  await sell('banany');

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

toHaveResolvedWith ​

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

Możesz wywołać tę asercję, aby sprawdzić, czy funkcja pomyślnie rozwiązała określoną wartość co najmniej raz. Wymaga przekazania funkcji szpiegującej do expect.

Jeśli funkcja zwróciła obietnicę, ale nie została ona jeszcze rozwiązana, to zakończy się niepowodzeniem.

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

test('funkcja szpiegująca rozwiązała produkt', async () => {
  const sell = vi.fn((product: string) => Promise.resolve({ product }));

  await sell('jabłka');

  expect(sell).toHaveResolvedWith({ product: 'jabłka' });
});

toHaveLastResolvedWith ​

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

Możesz wywołać tę asercję, aby sprawdzić, czy funkcja pomyślnie rozwiązała określoną wartość podczas ostatniego wywołania. Wymaga przekazania funkcji szpiegującej do expect.

Jeśli funkcja zwróciła obietnicę, ale nie została ona jeszcze rozwiązana, to zakończy się niepowodzeniem.

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

test('funkcja szpiegująca rozwiązuje banany przy ostatnim wywołaniu', async () => {
  const sell = vi.fn((product: string) => Promise.resolve({ product }));

  await sell('jabłka');
  await sell('banany');

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

toHaveNthResolvedWith ​

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

Możesz wywołać tę asercję, aby sprawdzić, czy funkcja pomyślnie rozwiązała określoną wartość w określonym wywołaniu. Wymaga przekazania funkcji szpiegującej do expect.

Jeśli funkcja zwróciła obietnicę, ale nie została ona jeszcze rozwiązana, to zakończy się niepowodzeniem.

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

test('funkcja szpiegująca zwraca banany przy drugim wywołaniu', async () => {
  const sell = vi.fn((product: string) => Promise.resolve({ product }));

  await sell('jabłka');
  await sell('banany');

  expect(sell).toHaveNthResolvedWith(2, { product: 'banany' });
});

toSatisfy ​

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

Ta asercja sprawdza, czy wartość spełnia określony predykat.

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

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

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

  it('przechodzi z negacją', () => {
    expect(2).not.toSatisfy(isOdd);
  });
});

resolves ​

  • Typ: Promisify<Assertions>

resolves ma na celu usunięcie zbędnego kodu podczas asercji kodu asynchronicznego. Użyj go, aby rozpakować wartość z oczekującej obietnicy i potwierdzić jej wartość za pomocą zwykłych asercji. Jeśli obietnica zostanie odrzucona, asercja zakończy się niepowodzeniem.

Zwraca ten sam obiekt Assertions, ale wszystkie dopasowania zwracają teraz Promise, więc będziesz musiał je awaitować. Działa również z asercjami chai.

Na przykład, jeśli masz funkcję, która wykonuje wywołanie API i zwraca jakieś dane, możesz użyć tego kodu, aby potwierdzić jej wartość zwracaną:

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

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

test('buyApples zwraca nowy identyfikator zapasów', async () => {
  // toEqual zwraca teraz obietnicę, więc MUSISZ ją awaitować
  await expect(buyApples()).resolves.toEqual({ id: 1 }); // Jest API
  await expect(buyApples()).resolves.to.equal({ id: 1 }); // Chai API
});

WARNING

Jeśli asercja nie zostanie awaitowana, otrzymasz fałszywie pozytywny test, który zawsze będzie przechodził. Aby upewnić się, że asercje zostały faktycznie wywołane, możesz użyć expect.assertions(number).

Od Vitest 3, jeśli metoda nie zostanie awaitowana, Vitest wyświetli ostrzeżenie na końcu testu. W Vitest 4, test zostanie oznaczony jako "nieudany", jeśli asercja nie zostanie awaitowana.

rejects ​

  • Typ: Promisify<Assertions>

rejects ma na celu usunięcie zbędnego kodu podczas asercji kodu asynchronicznego. Użyj go, aby rozpakować przyczynę odrzucenia obietnicy i potwierdzić jej wartość za pomocą zwykłych asercji. Jeśli obietnica zostanie pomyślnie rozwiązana, asercja zakończy się niepowodzeniem.

Zwraca ten sam obiekt Assertions, ale wszystkie dopasowania zwracają teraz Promise, więc będziesz musiał je awaitować. Działa również z asercjami chai.

Na przykład, jeśli masz funkcję, która zawodzi po jej wywołaniu, możesz użyć tego kodu, aby potwierdzić przyczynę:

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

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

test('buyApples zgłasza błąd, gdy nie podano id', async () => {
  // toThrow zwraca teraz obietnicę, więc MUSISZ ją awaitować
  await expect(buyApples()).rejects.toThrow('brak id');
});

WARNING

Jeśli asercja nie zostanie awaitowana, otrzymasz fałszywie pozytywny test, który zawsze będzie przechodził. Aby upewnić się, że asercje zostały faktycznie wywołane, możesz użyć expect.assertions(number).

Od Vitest 3, jeśli metoda nie zostanie awaitowana, Vitest wyświetli ostrzeżenie na końcu testu. W Vitest 4, test zostanie oznaczony jako "nieudany", jeśli asercja nie zostanie awaitowana.

expect.assertions ​

  • Typ: (count: number) => void

Po zakończeniu testu (sukcesie lub niepowodzeniu) sprawdź, czy podczas testu wywołano określoną liczbę asercji. Przydatnym przypadkiem byłoby sprawdzenie, czy kod asynchroniczny został wywołany.

Na przykład, jeśli mamy funkcję, która asynchronicznie wywołuje dwa dopasowania, możemy potwierdzić, że zostały one faktycznie wywołane.

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

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

test('wszystkie asercje są wywoływane', async () => {
  expect.assertions(2);
  function callback1(data) {
    expect(data).toBeTruthy();
  }
  function callback2(data) {
    expect(data).toBeTruthy();
  }

  await doAsync(callback1, callback2);
});

WARNING

Podczas używania assertions z asynchronicznymi testami współbieżnymi, należy użyć expect z lokalnego Kontekstu Testowego, aby upewnić się, że wykryto właściwy test.

expect.hasAssertions ​

  • Typ: () => void

Po zakończeniu testu (sukcesie lub niepowodzeniu) sprawdź, czy podczas testu wywołano co najmniej jedną asercję. Przydatnym przypadkiem byłoby sprawdzenie, czy kod asynchroniczny został wywołany.

Na przykład, jeśli masz kod, który wywołuje callback, możemy wykonać asercję wewnątrz callbacku, ale test zawsze przejdzie, jeśli nie sprawdzimy, czy asercja została wywołana.

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

const cbs = [];

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

// po wybraniu z bazy danych, wywołujemy wszystkie callbacki
function select(id) {
  return db.select({ id }).then(data => {
    return Promise.all(cbs.map(cb => cb(data)));
  });
}

test('callback został wywołany', async () => {
  expect.hasAssertions();
  onSelect(data => {
    // powinien zostać wywołany przy wyborze
    expect(data).toBeTruthy();
  });
  // jeśli nie awaitowany, test zakończy się niepowodzeniem
  // jeśli nie masz expect.hasAssertions(), test przejdzie
  await select(3);
});

expect.unreachable ​

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

Ta metoda służy do potwierdzenia, że dana linia nigdy nie powinna zostać osiągnięta.

Na przykład, jeśli chcemy przetestować, że build() rzuca błąd z powodu braku folderu src w katalogach docelowych, a także obsłużyć każdy błąd osobno, możemy to zrobić w następujący sposób:

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

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

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

test.each(errorDirs)('build kończy się niepowodzeniem z "%s"', async dir => {
  try {
    await build(dir);
    expect.unreachable('Kompilacja nie powinna się powieść');
  } catch (err: any) {
    expect(err).toBeInstanceOf(Error);
    expect(err.stack).toContain('build');

    switch (dir) {
      case 'no-src-folder':
        expect(err.message).toBe(`${dir}/src nie istnieje`);
        break;
      default:
        // aby wyczerpać wszystkie testy błędów
        expect.unreachable('Wszystkie przypadki błędów muszą być obsłużone');
        break;
    }
  }
});

expect.anything ​

  • Typ: () => any

Ten asymetryczny dopasowywacz, użyty z kontrolą równości, zawsze zwróci true. Przydatne, jeśli chcesz mieć pewność, że właściwość istnieje.

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

test('obiekt ma klucz "apples"', () => {
  expect({ apples: 22 }).toEqual({ apples: expect.anything() });
});

expect.any ​

  • Typ: (constructor: unknown) => any

Ten asymetryczny dopasowywacz, użyty z kontrolą równości, zwróci true tylko wtedy, gdy wartość jest instancją określonego konstruktora. Przydatne, jeśli masz wartość, która jest generowana za każdym razem i chcesz tylko wiedzieć, że istnieje z odpowiednim typem.

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

test('"id" jest liczbą', () => {
  expect({ id: generateId() }).toEqual({ id: expect.any(Number) });
});

expect.closeTo ​

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

expect.closeTo jest przydatne podczas porównywania liczb zmiennoprzecinkowych we właściwościach obiektów lub elementach tablic. Jeśli musisz porównać liczbę, użyj zamiast tego .toBeCloseTo.

Opcjonalny argument precision ogranicza liczbę cyfr do sprawdzenia po przecinku. Dla wartości domyślnej 2, kryterium testowe to Math.abs(expected - received) < 0.005 (czyli 10 ** -2 / 2).

Na przykład, ten test przechodzi z precyzją 5 cyfr:

js
test('porównaj liczby zmiennoprzecinkowe we właściwościach obiektu', () => {
  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

Użyty z kontrolą równości, ten asymetryczny dopasowywacz zwróci true, jeśli wartość jest tablicą i zawiera określone elementy.

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

test('koszyk zawiera fuji', () => {
  const basket = {
    varieties: ['Empire', 'Fuji', 'Gala'],
    count: 3,
  };
  expect(basket).toEqual({
    count: 3,
    varieties: expect.arrayContaining(['Fuji']),
  });
});

TIP

Możesz użyć expect.not z tym dopasowywaczem, aby zanegować oczekiwaną wartość.

expect.objectContaining ​

  • Typ: (expected: any) => any

Użyty z kontrolą równości, ten asymetryczny dopasowywacz zwróci true, jeśli wartość ma podobny kształt.

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

test('koszyk ma jabłka Empire', () => {
  const basket = {
    varieties: [
      {
        name: 'Empire',
        count: 1,
      },
    ],
  };
  expect(basket).toEqual({
    varieties: [expect.objectContaining({ name: 'Empire' })],
  });
});

TIP

Możesz użyć expect.not z tym dopasowywaczem, aby zanegować oczekiwaną wartość.

expect.stringContaining ​

  • Typ: (expected: any) => any

Użyty z kontrolą równości, ten asymetryczny dopasowywacz zwróci true, jeśli wartość jest ciągiem znaków i zawiera określony podciąg.

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

test('odmiana zawiera "Emp" w nazwie', () => {
  const variety = {
    name: 'Empire',
    count: 1,
  };
  expect(variety).toEqual({
    name: expect.stringContaining('Emp'),
    count: 1,
  });
});

TIP

Możesz użyć expect.not z tym dopasowywaczem, aby zanegować oczekiwaną wartość.

expect.stringMatching ​

  • Typ: (expected: any) => any

Użyty z kontrolą równości, ten asymetryczny dopasowywacz zwróci true, jeśli wartość jest ciągiem znaków i zawiera określony podciąg lub jeśli ciąg znaków pasuje do wyrażenia regularnego.

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

test('odmiana kończy się na "re"', () => {
  const variety = {
    name: 'Empire',
    count: 1,
  };
  expect(variety).toEqual({
    name: expect.stringMatching(/re$/),
    count: 1,
  });
});

TIP

Możesz użyć expect.not z tym dopasowywaczem, aby zanegować oczekiwaną wartość.

expect.addSnapshotSerializer ​

  • Typ: (plugin: PrettyFormatPlugin) => void

Ta metoda dodaje niestandardowe serializatory, które są wywoływane podczas tworzenia migawki. Jest to zaawansowana funkcja; jeśli chcesz dowiedzieć się więcej, przeczytaj przewodnik po niestandardowych serializatorach.

Jeśli dodajesz niestandardowe serializatory, powinieneś wywołać tę metodę wewnątrz setupFiles. Będzie to miało wpływ na każdą migawkę.

TIP

Jeśli wcześniej używałeś Vue CLI z Jest, możesz chcieć zainstalować jest-serializer-vue. W przeciwnym razie twoje migawki zostaną zawinięte w ciąg znaków, co spowoduje, że cudzysłowy " będą musiały być poprzedzone znakiem ucieczki.

expect.extend ​

  • Typ: (matchers: MatchersObject) => void

Możesz rozszerzyć domyślne dopasowania o własne. Ta funkcja służy do rozszerzania obiektu dopasowań o niestandardowe dopasowania.

Kiedy definiujesz dopasowania w ten sposób, tworzysz również asymetryczne dopasowania, które mogą być używane podobnie do expect.stringContaining.

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

test('niestandardowe dopasowania', () => {
  expect.extend({
    toBeFoo: (received, expected) => {
      if (received !== 'foo') {
        return {
          message: () => `oczekiwano, że ${received} będzie 'foo'`,
          pass: false,
        };
      }
    },
  });

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

TIP

Jeśli chcesz, aby twoje dopasowania pojawiały się w każdym teście, powinieneś wywołać tę metodę wewnątrz setupFiles.

Ta funkcja jest kompatybilna z expect.extend z Jest, więc każda biblioteka, która jej używa do tworzenia niestandardowych dopasowań, będzie działać z Vitest.

Jeśli używasz TypeScript, od Vitest 0.31.0 możesz rozszerzyć domyślny interfejs Assertion w pliku deklaracji globalnej (np. vitest.d.ts) za pomocą poniższego kodu:

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

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

WARNING

Nie zapomnij dołączyć pliku deklaracji globalnej do swojego tsconfig.json.

TIP

Jeśli chcesz dowiedzieć się więcej, sprawdź przewodnik po rozszerzaniu dopasowań.

expect.addEqualityTesters ​

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

Możesz użyć tej metody do zdefiniowania niestandardowych testerów, które są metodami używanymi przez dopasowania do testowania, czy dwa obiekty są równe. Jest ona kompatybilna z expect.addEqualityTesters z Jest.

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('niestandardowy tester równości', () => {
  expect(new AnagramComparator('listen')).toEqual(
    new AnagramComparator('silent')
  );
});
Pager
Poprzednia stronaVi
Następna stronaexpectTypeOf

Opublikowano na licencji MIT.

Copyright (c) 2021-Present Vitest Team

https://vitest.dev/api/expect

Opublikowano na licencji MIT.

Copyright (c) 2021-Present Vitest Team