Skip to content
Vitest 1
Main Navigation PrůvodceAPIKonfiguracePokročilý
1.6.1
0.34.6

čeština

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

čeština

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

Vzhled

Sidebar Navigation

Průvodce

Proč Vitest

Začínáme

Funkce

Workspace

Rozhraní příkazového řádku

Filtrování testů

Reportéři

Pokrytí

Snímky

Mockování

Testování typů

Vitest UI

Režim prohlížeče

Testování ve zdrojovém kódu

Kontext testu

Testovací prostředí

Rozšíření matcherů/porovnávačů

Integrace do IDE

Ladění

Srovnání s jinými testovacími nástroji

Průvodce migrací

Běžné chyby

Zvýšení výkonu

API

Referenční příručka k Test API

Mock funkce

Vi

expect

expectTypeOf

assert

assertType

Konfigurace

Správa konfiguračního souboru pro Vitest

Konfigurace Vitest

Na této stránce

expect ​

Následující typy se používají v typových signaturách níže:

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

expect slouží k vytváření asercí. Aserce jsou v tomto kontextu funkce, které se volají k ověření tvrzení. Vitest ve výchozím nastavení poskytuje aserce chai a také aserce kompatibilní s Jest, které jsou postaveny na chai.

Například tento kód ověřuje, že hodnota input je rovna 2. Pokud tomu tak není, aserce vyvolá chybu a test selže.

ts
import { expect } from 'vitest';

const input = Math.sqrt(4);

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

Z technického hlediska tento příklad nepoužívá funkci test, takže v konzoli uvidíte chybu Node.js místo výstupu Vitest. Více informací o test naleznete v Referenci API Test.

expect lze také použít staticky pro přístup k funkcím matcherů, které jsou popsány dále, a dalším.

WARNING

expect nemá žádný vliv na testování typů, pokud výraz neobsahuje typovou chybu. Pro použití Vitest jako kontrolu typů použijte expectTypeOf nebo assertType.

soft ​

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

expect.soft funguje podobně jako expect, ale po neúspěšné aserci neukončí provádění testu, nýbrž pokračuje v běhu a označí selhání jako selhání testu. Všechny chyby, které se během testu vyskytnou, se zobrazí po dokončení testu.

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

test('expect.soft test', () => {
  expect.soft(1 + 1).toBe(3); // označí test jako neúspěšný a pokračuje v jeho provádění
  expect.soft(1 + 2).toBe(4); // označí test jako neúspěšný a pokračuje v jeho provádění
});
// Na konci testu se zobrazí výše uvedené chyby.

Lze jej také použít s expect. Pokud aserce expect selže, test se ukončí a zobrazí se všechny chyby.

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

test('expect.soft test', () => {
  expect.soft(1 + 1).toBe(3); // označí test jako neúspěšný a pokračuje v jeho provádění
  expect(1 + 2).toBe(4); // selže a ukončí test, zobrazí se všechny předchozí chyby
  expect.soft(1 + 3).toBe(5); // nebude vykonána
});

WARNING

expect.soft lze použít pouze uvnitř funkce test.

not ​

Použití not neguje aserci. Například tento kód ověřuje, že hodnota input není rovna 2. Pokud se rovná, aserce vyvolá chybu a test selže.

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 slouží k ověření, zda se primitivní hodnoty rovnají nebo zda objekty sdílejí stejnou referenci. Je to ekvivalentní zápisu expect(Object.is(3, 3)).toBe(true). Pokud objekty nejsou stejné, ale chcete zkontrolovat, zda jsou jejich struktury identické, použijte toEqual.

Například kód níže kontroluje, zda má obchodník 13 jablek.

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; // stejná reference

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

Vyhněte se používání toBe s čísly s plovoucí desetinnou čárkou. Protože je JavaScript zaokrouhluje, 0.1 + 0.2 není striktně 0.3. Pro spolehlivé ověření čísel s plovoucí desetinnou čárkou použijte aserci toBeCloseTo.

toBeCloseTo ​

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

Použijte toBeCloseTo k porovnání čísel s plovoucí desetinnou čárkou. Volitelný argument numDigits určuje počet číslic, které se mají kontrolovat za desetinnou čárkou. Například:

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

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

test('decimals are rounded to 5 after the point', () => {
  // 0.2 + 0.1 je 0.30000 | "000000000004" odstraněno
  expect(0.2 + 0.1).toBeCloseTo(0.3, 5);
  // nic z 0.30000000000000004 není odstraněno
  expect(0.2 + 0.1).not.toBeCloseTo(0.3, 50);
});

toBeDefined ​

  • Typ: () => Awaitable<void>

toBeDefined ověřuje, že hodnota není rovna undefined. Užitečné je to například pro kontrolu, zda funkce něco vrátila.

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

function getApples() {
  return 3;
}

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

toBeUndefined ​

  • Typ: () => Awaitable<void>

Opakem toBeDefined je toBeUndefined, který ověřuje, že se hodnota rovná undefined. Užitečné je to například pro kontrolu, zda funkce nic nevrátila.

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

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

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

toBeTruthy ​

  • Typ: () => Awaitable<void>

toBeTruthy ověřuje, že hodnota je true, když je převedena na boolean. Užitečné, pokud potřebujete pouze zjistit, zda lze hodnotu převést na true.

Například, když máte tento kód, nezajímáte se o návratovou hodnotu stocks.getInfo - může to být složitý objekt, řetězec nebo cokoli jiného. Kód bude stále fungovat.

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

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

Takže pokud chcete otestovat, že stocks.getInfo bude truthy, můžete napsat:

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

const stocks = new Stocks();

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

V JavaScriptu je vše považováno za truthy hodnotu, kromě false, null, undefined, NaN, 0, -0, 0n, "" a document.all.

toBeFalsy ​

  • Typ: () => Awaitable<void>

toBeFalsy ověřuje, že hodnota je false, když je převedena na boolean. Užitečné, pokud potřebujete pouze zjistit, zda lze hodnotu převést na false.

Například, pokud máte tento kód, nezáleží na konkrétní návratové hodnotě stocks.stockFailed, důležité je, že vrací falsy hodnotu.

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

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

Takže pokud chcete otestovat, že stocks.stockFailed bude falsy, můžete napsat:

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

const stocks = new Stocks();

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

V JavaScriptu je vše považováno za truthy hodnotu, kromě false, null, undefined, NaN, 0, -0, 0n, "" a document.all.

toBeNull ​

  • Typ: () => Awaitable<void>

toBeNull jednoduše ověřuje, zda je hodnota null. Alias pro .toBe(null).

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

function apples() {
  return null;
}

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

toBeNaN ​

  • Typ: () => Awaitable<void>

toBeNaN jednoduše ověřuje, zda je hodnota NaN. Alias pro .toBe(NaN).

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

let i = 0;

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

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

toBeTypeOf ​

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

toBeTypeOf ověřuje, zda má skutečná hodnota typ, který byl přijat.

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

const actual = 'stock';

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

toBeInstanceOf ​

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

toBeInstanceOf ověřuje, zda je skutečná hodnota instancí třídy, která byla přijata.

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

const stocks = new Stocks();

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

toBeGreaterThan ​

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

toBeGreaterThan ověřuje, zda je skutečná hodnota větší než hodnota, která byla přijata. Pokud jsou hodnoty stejné, test selže.

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

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

toBeGreaterThanOrEqual ​

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

toBeGreaterThanOrEqual ověřuje, zda je skutečná hodnota větší než přijatá hodnota nebo se jí rovná.

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

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

toBeLessThan ​

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

toBeLessThan ověřuje, zda je skutečná hodnota menší než hodnota, která byla přijata. Pokud jsou hodnoty stejné, test selže.

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

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

toBeLessThanOrEqual ​

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

toBeLessThanOrEqual ověřuje, zda je skutečná hodnota menší než přijatá hodnota nebo se jí rovná.

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

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

toEqual ​

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

toEqual ověřuje, zda se skutečná hodnota rovná hodnotě, která byla přijata, nebo má stejnou strukturu, pokud se jedná o objekt (porovnává je rekurzivně). Rozdíl mezi toEqual a toBe můžete vidět v tomto příkladu:

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

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

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

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

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

WARNING

Hloubková rovnost nebude provedena pro objekty Error. Pro rovnost se bere v úvahu pouze vlastnost message chyby. Chcete-li upravit rovnost pro kontrolu jiných vlastností než message, použijte expect.addEqualityTesters. Chcete-li otestovat, zda byla vyvolána výjimka, použijte kontrolu toThrowError.

toStrictEqual ​

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

toStrictEqual ověřuje, zda se skutečná hodnota rovná hodnotě, která byla přijata, nebo má stejnou strukturu, pokud se jedná o objekt (porovnává je rekurzivně), a stejného typu.

Rozdíly od .toEqual:

  • Klíče s vlastnostmi undefined jsou kontrolovány. Např. {a: undefined, b: 2} se neshoduje s {b: 2} při použití .toStrictEqual.
  • Kontroluje se, zda je pole řídké. Např. [, 1] se neshoduje s [undefined, 1] při použití .toStrictEqual.
  • Typy objektů jsou kontrolovány, zda jsou stejné. Např. Instance třídy s atributy a a b se nebude rovnat literálovému objektu s atributy a a b.
ts
import { expect, test } from 'vitest';

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

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

toContain ​

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

toContain ověřuje, zda je skutečná hodnota v poli. toContain může také zkontrolovat, zda je řetězec podřetězcem jiného řetězce. Od verze Vitest 1.0, pokud spouštíte testy v prostředí podobném prohlížeči, může toto tvrzení také zkontrolovat, zda je třída obsažena v classList, nebo zda je prvek uvnitř jiného.

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

test('the fruit list contains orange', () => {
  expect(getAllFruits()).toContain('orange');

  const element = document.querySelector('#el');
  // element has a class
  expect(element.classList).toContain('flex');
  // element is inside another one
  expect(document.querySelector('#wrapper')).toContain(element);
});

toContainEqual ​

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

toContainEqual ověřuje, zda je v poli obsažena položka se specifickou strukturou a hodnotami. Funguje jako toEqual uvnitř pro každý prvek.

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

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

toHaveLength ​

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

toHaveLength ověřuje, zda má objekt vlastnost .length a zda je nastavena na určitou hodnotu.

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

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

  expect('').not.toHaveLength(3); // nemá vlastnost .length rovnou 3
  expect({ length: 3 }).toHaveLength(3);
});

toHaveProperty ​

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

toHaveProperty ověřuje, zda objekt obsahuje vlastnost se zadaným klíčem key.

Můžete také zadat volitelný argument hodnoty, který slouží k hloubkovému porovnání (deep equality), podobně jako u matcheru toEqual, pro porovnání hodnoty vlastnosti.

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

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

test('John Doe Invoice', () => {
  expect(invoice).toHaveProperty('isActive'); // ověřte existenci klíče
  expect(invoice).toHaveProperty('total_amount', 5000); // ověřte existenci klíče a shodu hodnoty

  expect(invoice).not.toHaveProperty('account'); // ověřte, že klíč neexistuje

  // Hloubkové odkazování pomocí tečkové notace
  expect(invoice).toHaveProperty('customer.first_name');
  expect(invoice).toHaveProperty('customer.last_name', 'Doe');
  expect(invoice).not.toHaveProperty('customer.location', 'India');

  // Hloubkové odkazování pomocí pole obsahujícího klíč
  expect(invoice).toHaveProperty('items[0].type', 'apples');
  expect(invoice).toHaveProperty('items.0.type', 'apples'); // tečková notace také funguje

  // Hloubkové odkazování pomocí pole obsahujícího cestu ke klíči
  expect(invoice).toHaveProperty(['items', 0, 'type'], 'apples');
  expect(invoice).toHaveProperty(['items', '0', 'type'], 'apples'); // notace pomocí řetězců také funguje

  // Zabalte klíč do pole, abyste zabránili jeho parsování jako hloubkového odkazu
  expect(invoice).toHaveProperty(['P.O'], '12345');
});

toMatch ​

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

toMatch ověřuje, zda řetězec odpovídá regulárnímu výrazu nebo jinému řetězci.

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

test('top fruits', () => {
  expect('top fruits include apple, orange and grape').toMatch(/apple/);
  expect('applefruits').toMatch('fruit'); // toMatch akceptuje i řetězec
});

toMatchObject ​

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

toMatchObject ověřuje, zda objekt odpovídá podmnožině vlastností jiného objektu.

Můžete také předat pole objektů. To je užitečné, pokud chcete zkontrolovat, zda se dvě pole shodují v počtu prvků, na rozdíl od arrayContaining, které umožňuje další prvky v přijatém poli.

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

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

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

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

test('the number of elements must match exactly', () => {
  // Ověřte, že se pole objektů shoduje
  expect([{ foo: 'bar' }, { baz: 1 }]).toMatchObject([
    { foo: 'bar' },
    { baz: 1 },
  ]);
});

toThrowError ​

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

  • Alias: toThrow

toThrowError ověřuje, zda funkce při volání vyvolá chybu.

Můžete zadat volitelný argument pro otestování, zda je vyvolána konkrétní chyba:

  • regulární výraz: chybová zpráva odpovídá vzoru
  • řetězec: chybová zpráva obsahuje podřetězec

TIP

Kód, který má vyvolat chybu, musíte zabalit do funkce, jinak nebude chyba zachycena a test selže.

Například, pokud chceme otestovat, zda getFruitStock('pineapples') vyvolá chybu, můžeme napsat:

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

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

  // Do some other stuff
}

test('throws on pineapples', () => {
  // Test that the error message contains "stock" somewhere: these are equivalent
  expect(() => getFruitStock('pineapples')).toThrowError(/stock/);
  expect(() => getFruitStock('pineapples')).toThrowError('stock');

  // Test the exact error message
  expect(() => getFruitStock('pineapples')).toThrowError(
    /^Pineapples are not in stock$/
  );
});

TIP

Pro testování asynchronních funkcí použijte v kombinaci s rejects.

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

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

toMatchSnapshot ​

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

Zajišťuje, že hodnota odpovídá nejnovějšímu snímku (snapshot).

Můžete zadat volitelný řetězcový argument hint, který se připojí k názvu testu. Ačkoli Vitest vždy připojí číslo na konec názvu snímku, krátké popisné nápovědy mohou být užitečnější než čísla pro rozlišení více snímků v jednom bloku it nebo test. Vitest třídí snímky podle názvu v odpovídajícím souboru .snap.

TIP

Pokud snímek nesouhlasí a způsobí selhání testu, a tento nesoulad je očekávaný, můžete stiskem klávesy u snímek jednorázově aktualizovat. Nebo můžete předat možnosti CLI -u nebo --update, aby Vitest vždy aktualizoval testy.

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

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

Můžete také zadat tvar objektu, pokud testujete pouze tvar objektu a nepotřebujete, aby byl 100% kompatibilní:

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

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

toMatchInlineSnapshot ​

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

Zajišťuje, že hodnota odpovídá nejnovějšímu inline snímku (snapshot).

Vitest přidá a aktualizuje argument řetězce inlineSnapshot do porovnávače v testovacím souboru (místo externího souboru .snap).

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

test('matches inline snapshot', () => {
  const data = { foo: new Set(['bar', 'snapshot']) };
  // Vitest will update following content when updating the snapshot
  expect(data).toMatchInlineSnapshot(`
    {
      "foo": Set {
        "bar",
        "snapshot",
      },
    }
  `);
});

Můžete také zadat tvar objektu, pokud testujete pouze tvar objektu a nepotřebujete, aby byl 100% kompatibilní:

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

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

toMatchFileSnapshot 0.30.0+ ​

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

Porovná nebo aktualizuje snímek (snapshot) s obsahem souboru explicitně určeného cestou (místo souboru .snap).

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

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

Všimněte si, že protože operace se systémem souborů je asynchronní, musíte použít await s toMatchFileSnapshot().

toThrowErrorMatchingSnapshot ​

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

Stejné jako toMatchSnapshot, ale očekává stejnou hodnotu jako toThrowError.

toThrowErrorMatchingInlineSnapshot ​

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

Stejné jako toMatchInlineSnapshot, ale očekává stejnou hodnotu jako toThrowError.

toHaveBeenCalled ​

  • Typ: () => Awaitable<void>

Toto tvrzení je užitečné pro testování, zda byla funkce skutečně volána. Vyžaduje předání špehovací funkce (spy function) do expect.

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

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

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

  expect(buySpy).not.toHaveBeenCalled();

  market.buy('apples', 10);

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

toHaveBeenCalledTimes ​

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

Toto tvrzení kontroluje, zda byla funkce volána určitý počet krát. Vyžaduje předání špehovací funkce (spy function) do expect.

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

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

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

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

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

toHaveBeenCalledWith ​

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

Toto tvrzení kontroluje, zda byla funkce volána alespoň jednou s určitými parametry. Vyžaduje předání špehovací funkce (spy function) do expect.

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

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

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

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

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

toHaveBeenLastCalledWith ​

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

Toto tvrzení kontroluje, zda byla funkce volána s určitými parametry při posledním vyvolání. Vyžaduje předání špehovací funkce (spy function) do expect.

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

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

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

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

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

toHaveBeenNthCalledWith ​

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

Toto tvrzení kontroluje, zda byla funkce volána s určitými parametry v určitém pořadí volání. Počet začíná na 1. Takže pro kontrolu druhého volání byste napsali .toHaveBeenNthCalledWith(2, ...)

Vyžaduje předání špehovací funkce (spy function) do expect.

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

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

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

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

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

toHaveReturned ​

  • Typ: () => Awaitable<void>

Toto tvrzení kontroluje, zda funkce úspěšně vrátila hodnotu alespoň jednou (tj. že nevyvolala chybu). Vyžaduje předání špehovací funkce (spy function) do expect.

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

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

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

  const price = getPriceSpy(10);

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

toHaveReturnedTimes ​

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

Toto tvrzení kontroluje, zda funkce úspěšně vrátila hodnotu přesný počet krát (tj. že nevyvolala chybu). Vyžaduje předání špehovací funkce (spy function) do expect.

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

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

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

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

toHaveReturnedWith ​

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

Tuto aserci použijte ke kontrole, zda funkce alespoň jednou vrátila zadanou hodnotu. Vyžaduje, aby byla do expect předána sledovací funkce (mock function).

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

test('sledovací funkce vrací produkt', () => {
  const sell = vi.fn((product: string) => ({ product }));

  sell('apples');

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

toHaveLastReturnedWith ​

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

Tuto aserci použijte ke kontrole, zda funkce při svém posledním volání vrátila zadanou hodnotu. Vyžaduje, aby byla do expect předána sledovací funkce (mock function).

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

test('sledovací funkce při posledním volání vrací banány', () => {
  const sell = vi.fn((product: string) => ({ product }));

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

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

toHaveNthReturnedWith ​

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

Tuto aserci použijte ke kontrole, zda funkce při konkrétním volání (určeném indexem) vrátila zadanou hodnotu. Vyžaduje, aby byla do expect předána sledovací funkce (mock function).

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

test('sledovací funkce při druhém volání vrací banány', () => {
  const sell = vi.fn((product: string) => ({ product }));

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

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

toSatisfy ​

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

Tato aserce ověřuje, zda hodnota splňuje zadaný predikát (podmínku).

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

  it('projde s hodnotou 1', () => {
    expect(1).toSatisfy(isOdd);
  });

  it('projde při negaci', () => {
    expect(2).not.toSatisfy(isOdd);
  });
});

resolves ​

  • Typ: Promisify<Assertions>

resolves zjednodušuje psaní asercí pro asynchronní kód. Použijte jej k získání hodnoty z vyřešené promise a ověření této hodnoty pomocí standardních asercí. Pokud promise bude zamítnuta (rejected), aserce selže.

Vrací stejný objekt Assertions, ale všechny matchery nyní vrací Promise, takže je nutné je awaitovat. Funguje také s asercemi chai.

Například, pokud máte funkci, která provádí volání API a vrací data, můžete použít tento kód k ověření její návratové hodnoty:

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

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

test('buyApples vrací nové ID skladu', async () => {
  // toEqual nyní vrací promise, takže ji MUSÍTE awaitovat
  await expect(buyApples()).resolves.toEqual({ id: 1 }); // jest API
  await expect(buyApples()).resolves.to.equal({ id: 1 }); // chai API
});

WARNING

Pokud aserce není awaitována, dojde k falešně pozitivnímu testu, který projde pokaždé. Abyste se ujistili, že jsou aserce skutečně volány, můžete použít expect.assertions(number).

rejects ​

  • Typ: Promisify<Assertions>

rejects zjednodušuje psaní asercí pro asynchronní kód. Použijte jej k získání důvodu zamítnutí (rejection) promise a ověření této hodnoty pomocí standardních asercí. Pokud promise bude vyřešena (resolved) úspěšně, aserce selže.

Vrací stejný objekt Assertions, ale všechny matchery nyní vrací Promise, takže je nutné je awaitovat. Funguje také s asercemi chai.

Například, pokud máte funkci, která selže, můžete použít tento kód k ověření důvodu selhání:

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

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

test('buyApples vyvolá chybu, pokud není zadáno ID', async () => {
  // toThrow nyní vrací promise, takže ji MUSÍTE awaitovat
  await expect(buyApples()).rejects.toThrow('no id');
});

WARNING

Pokud aserce není awaitována, dojde k falešně pozitivnímu testu, který projde pokaždé. Abyste se ujistili, že byly aserce skutečně volány, můžete použít expect.assertions(number).

expect.assertions ​

  • Typ: (count: number) => void

Ověří, zda byl během testu volán zadaný počet asercí. To je užitečné například pro kontrolu, zda byl volán asynchronní kód. Tato kontrola se provádí po dokončení testu (úspěšném či neúspěšném).

Například, pokud máme funkci, která asynchronně volá dva matchery, můžeme ověřit, že byly skutečně volány.

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

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

test('všechny aserce jsou volány', async () => {
  expect.assertions(2);
  function callback1(data) {
    expect(data).toBeTruthy();
  }
  function callback2(data) {
    expect(data).toBeTruthy();
  }

  await doAsync(callback1, callback2);
});

WARNING

Při použití assertions s asynchronními souběžnými testy musí být použit expect z lokálního Test Context, aby byl zajištěn správný test.

expect.hasAssertions ​

  • Typ: () => void

Ověří, zda byla během testu volána alespoň jedna aserce. To je užitečné například pro kontrolu, zda byl volán asynchronní kód. Tato kontrola se provádí po dokončení testu (úspěšném či neúspěšném).

Například, pokud máte kód, který volá callback, můžeme provést aserci uvnitř callbacku, ale test vždy projde, pokud nezkontrolujeme, zda byla aserce volána.

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

const cbs = [];

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

// po výběru z databáze voláme všechny callbacky
function select(id) {
  return db.select({ id }).then(data => {
    return Promise.all(cbs.map(cb => cb(data)));
  });
}

test('callback byl volán', async () => {
  expect.hasAssertions();
  onSelect(data => {
    // měl by být volán při select
    expect(data).toBeTruthy();
  });
  // pokud chybí await, test selže
  // bez expect.hasAssertions() test projde
  await select(3);
});

expect.unreachable ​

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

Tato metoda slouží k ověření, že daný řádek kódu by neměl být nikdy vykonán. Pokud je vykonán, test selže.

Například, pokud chceme otestovat, že funkce build() vyvolá výjimku, protože obdržela adresáře, které neobsahují složku src, a zároveň chceme zpracovat každou chybu individuálně, můžeme postupovat takto:

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

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

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

test.each(errorDirs)('build neprojde pro "%s"', async dir => {
  try {
    await build(dir);
    expect.unreachable('Build by neměl projít');
  } catch (err: any) {
    expect(err).toBeInstanceOf(Error);
    expect(err.stack).toContain('build');

    switch (dir) {
      case 'no-src-folder':
        expect(err.message).toBe(`${dir}/src does not exist`);
        break;
      default:
        // pro vyčerpání všech chybových testů
        expect.unreachable('Všechny testy chyb musí být ošetřeny');
        break;
    }
  }
});

expect.anything ​

  • Typ: () => any

Tento asymetrický matcher, pokud je použit s operátorem rovnosti, vždy vrátí true. Je užitečný, pokud chcete ověřit pouze existenci dané vlastnosti.

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

test('objekt má klíč "apples"', () => {
  expect({ apples: 22 }).toEqual({ apples: expect.anything() });
});

expect.any ​

  • Typ: (constructor: unknown) => any

Tento asymetrický matcher, pokud je použit s operátorem rovnosti, vrátí true pouze v případě, že je hodnota instancí zadaného konstruktoru (typu). Je užitečný, pokud máte hodnotu, která je generována dynamicky, a chcete ověřit pouze její typ.

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

test('"id" je číslo', () => {
  expect({ id: generateId() }).toEqual({ id: expect.any(Number) });
});

expect.closeTo 1.0.0+ ​

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

expect.closeTo je užitečné při porovnávání čísel s plovoucí desetinnou čárkou ve vlastnostech objektu nebo v položkách pole. Pokud potřebujete porovnat číslo, použijte místo toho .toBeCloseTo.

Volitelný argument numDigits omezuje počet číslic, které se mají zkontrolovat za desetinnou čárkou. Pro výchozí hodnotu 2 je testovacím kritériem Math.abs(expected - received) < 0.005 (tj. 10 ** -2 / 2).

Například tento test projde s přesností na 5 číslic:

js
test('porovnat float ve vlastnostech objektu', () => {
  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

Pokud je tento asymetrický matcher použit s operátorem rovnosti, vrátí true v případě, že je hodnota pole a obsahuje všechny zadané prvky.

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

test('košík obsahuje fuji', () => {
  const basket = {
    varieties: ['Empire', 'Fuji', 'Gala'],
    count: 3,
  };
  expect(basket).toEqual({
    count: 3,
    varieties: expect.arrayContaining(['Fuji']),
  });
});

TIP

Můžete použít expect.not s tímto matcherem k negaci očekávané hodnoty.

expect.objectContaining ​

  • Typ: (expected: any) => any

Pokud je tento asymetrický matcher použit s operátorem rovnosti, vrátí true v případě, že hodnota je objekt a má podobnou strukturu (obsahuje alespoň zadané vlastnosti).

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

test('košík má jablka empire', () => {
  const basket = {
    varieties: [
      {
        name: 'Empire',
        count: 1,
      },
    ],
  };
  expect(basket).toEqual({
    varieties: [expect.objectContaining({ name: 'Empire' })],
  });
});

TIP

Můžete použít expect.not s tímto matcherem k negaci očekávané hodnoty.

expect.stringContaining ​

  • Typ: (expected: any) => any

Pokud je tento asymetrický matcher použit s operátorem rovnosti, vrátí true v případě, že hodnota je řetězec a obsahuje zadaný podřetězec.

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

test('odrůda má v názvu "Emp"', () => {
  const variety = {
    name: 'Empire',
    count: 1,
  };
  expect(variety).toEqual({
    name: expect.stringContaining('Emp'),
    count: 1,
  });
});

TIP

Můžete použít expect.not s tímto matcherem k negaci očekávané hodnoty.

expect.stringMatching ​

  • Typ: (expected: any) => any

Pokud je tento asymetrický matcher použit s operátorem rovnosti, vrátí true v případě, že hodnota je řetězec a obsahuje zadaný podřetězec, nebo pokud řetězec odpovídá zadanému regulárnímu výrazu.

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

test('odrůda končí na "re"', () => {
  const variety = {
    name: 'Empire',
    count: 1,
  };
  expect(variety).toEqual({
    name: expect.stringMatching(/re$/),
    count: 1,
  });
});

TIP

Můžete použít expect.not s tímto matcherem k negaci očekávané hodnoty.

expect.addSnapshotSerializer ​

  • Typ: (plugin: PrettyFormatPlugin) => void

Tato metoda přidává vlastní serializátory, které se používají při vytváření snapshotů. Toto je pokročilá vlastnost. Pro více informací si přečtěte průvodce vlastními serializátory.

Pokud používáte vlastní serializátory, doporučuje se volat tuto metodu uvnitř setupFiles. To ovlivní každý snapshot.

TIP

Pokud jste dříve používali Vue CLI s Jest, možná budete chtít nainstalovat jest-serializer-vue. V opačném případě budou vaše snapshoty zabaleny do řetězce, což povede k escapování znaků "."

expect.extend ​

  • Typ: (matchers: MatchersObject) => void

Můžete rozšířit sadu výchozích matcherů o vlastní. Tato funkce slouží k rozšíření objektu matcherů o vlastní implementace.

Při definování matcherů tímto způsobem se automaticky vytvoří i odpovídající asymetrické matchery, které lze použít například jako expect.stringContaining.

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

test('vlastní matchery', () => {
  expect.extend({
    toBeFoo: (received, expected) => {
      if (received !== 'foo') {
        return {
          message: () => `očekává se, že ${received} bude foo`,
          pass: false,
        };
      }
    },
  });

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

TIP

Pokud chcete, aby byly vaše matchery dostupné v každém testu, doporučuje se volat tuto metodu uvnitř setupFiles.

Tato funkce je kompatibilní s funkcí expect.extend z Jestu, takže jakákoli knihovna, která ji používá k vytváření vlastních matcherů, bude bez problémů fungovat i s Vitest.

Pokud používáte TypeScript, můžete od verze Vitest 0.31.0 rozšířit výchozí rozhraní Assertion v souboru s ambientní deklarací (např. vitest.d.ts) pomocí následujícího kódu:

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

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

WARNING

Ujistěte se, že jste zahrnuli soubor s ambientní deklarací do konfigurace tsconfig.json.

TIP

Pokud se chcete dozvědět více, podívejte se na průvodce rozšířením matcherů.

expect.addEqualityTesters 1.2.0+ ​

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

Tuto metodu můžete použít k definování vlastních testerů, což jsou metody používané nástroji pro porovnávání k testování, zda se dva objekty rovnají. Je kompatibilní s expect.addEqualityTesters v Jestu.

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

class AnagramComparator {
  public word: string;

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

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

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

    return sortedStr1 === sortedStr2;
  }
}

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

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

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

expect.addEqualityTesters([areAnagramsEqual]);

test('vlastní tester rovnosti', () => {
  expect(new AnagramComparator('listen')).toEqual(
    new AnagramComparator('silent')
  );
});
Pager
Předchozí stránkaVi
Další stránkaexpectTypeOf

Vydáno pod licencí MIT.

Copyright (c) 2024 Mithril Contributors

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

Vydáno pod licencí MIT.

Copyright (c) 2024 Mithril Contributors