Skip to content
Vitest 3
Main Navigation Průvodce & APIKonfiguraceRežim prohlížečePokročilé API
3.2.0
2.1.9
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

Úvod

Proč Vitest

Začínáme

Funkce

Konfigurace Vitestu

API

Testovací reference API

Mockovací funkce

Vi

expect

expectTypeOf

assert

assertType

Průvodce

Rozhraní příkazového řádku

Filtrování testů

Testovací projekty

Generátory zpráv

Pokrytí kódu

Snímky

Mockování

Paralelní zpracování

Typové testování

Vitest UI

Testování přímo ve zdrojovém kódu

Testovací kontext

Anotace testů

Testovací prostředí

Rozšíření matcherů

Integrace s IDE

Ladění

Běžné chyby

Průvodce migrací

Migrace na Vitest 3.0

Migrace z Jest

Výkon

Profilování výkonu testů

Zlepšení výkonu

Režim prohlížeče

Rozšířené API

Srovnání

Na této stránce

Vi ​

Vitest poskytuje pomocné funkce, které jsou dostupné prostřednictvím globálního pomocníka vi. Můžete k němu přistupovat globálně (pokud je povolena globální konfigurace), nebo jej importovat přímo z vitest:

js
import { vi } from 'vitest';

Mockování modulů ​

Tato sekce popisuje API, které můžete použít při mockování modulů. Mějte na paměti, že Vitest nepodporuje mockování modulů importovaných pomocí require().

vi.mock ​

  • Typ: (path: string, factory?: MockOptions | ((importOriginal: () => unknown) => unknown)) => void
  • Typ: <T>(path: Promise<T>, factory?: MockOptions | ((importOriginal: () => T) => T | Promise<T>)) => void

Nahradí všechny importované moduly z poskytnuté path jiným modulem. V cestě můžete použít nakonfigurované Vite aliasy. Volání vi.mock je hoistováno, takže nezáleží na tom, kde ho zavoláte. Vždy bude provedeno před všemi importy. Pokud potřebujete odkazovat na některé proměnné mimo jeho rozsah, můžete je definovat uvnitř vi.hoisted a odkazovat na ně uvnitř vi.mock.

WARNING

vi.mock funguje pouze pro moduly, které byly importovány klíčovým slovem import. Nefunguje s require.

Aby bylo možné vi.mock hoistovat, Vitest staticky analyzuje vaše soubory. To znamená, že vi, které nebylo přímo importováno z balíčku vitest (například z nějakého pomocného souboru), nelze použít. Použijte vi.mock s vi importovaným z vitest, nebo povolte konfigurační možnost globals.

Vitest nebude mockovat moduly, které byly importovány uvnitř inicializačního souboru, protože jsou v době spuštění testovacího souboru již cachovány. Můžete zavolat vi.resetModules() uvnitř vi.hoisted pro vymazání všech cachovaných modulů před spuštěním testovacího souboru.

Pokud je definována funkce factory, všechny importy vrátí její výsledek. Vitest volá factory pouze jednou a cachuje výsledky pro všechny následné importy, dokud není zavoláno vi.unmock nebo vi.doUnmock.

Na rozdíl od jest může být factory asynchronní. Můžete použít vi.importActual nebo pomocnou funkci s factory předanou jako první argument a získat původní modul uvnitř.

Můžete také poskytnout objekt s vlastností spy namísto factory funkce. Pokud je spy true, pak Vitest automockuje modul jako obvykle, ale nepřepíše implementaci exportů. To je užitečné, pokud chcete pouze ověřit, že exportovaná metoda byla správně volána jinou metodou.

ts
import { calculator } from './src/calculator.ts';

vi.mock('./src/calculator.ts', { spy: true });

// volá původní implementaci,
// ale umožňuje pozdější ověření chování
const result = calculator(1, 2);

expect(result).toBe(3);
expect(calculator).toHaveBeenCalledWith(1, 2);
expect(calculator).toHaveReturned(3);

Vitest také podporuje promise modulu namísto řetězce v metodách vi.mock a vi.doMock pro lepší podporu IDE. Když je soubor přesunut, cesta se aktualizuje a importOriginal automaticky zdědí typ. Použití této signatury také vynutí, aby návratový typ factory byl kompatibilní s původním modulem (při zachování volitelných exportů).

ts
// @filename: ./path/to/module.js
export declare function total(...numbers: number[]): number;
// @filename: test.js
import { vi } from 'vitest';
// ---cut---
vi.mock(import('./path/to/module.js'), async importOriginal => {
  const mod = await importOriginal(); // typ je odvozen
  //    ^?
  return {
    ...mod,
    // nahradit některé exporty
    total: vi.fn(),
  };
});

Pod kapotou Vitest stále pracuje s řetězcem, nikoli s objektem modulu.

Pokud však používáte TypeScript s aliasy paths nakonfigurovanými v tsconfig.json, kompilátor nebude schopen správně vyřešit typy importů. Aby to fungovalo, ujistěte se, že nahradíte všechny aliasované importy jejich odpovídajícími relativními cestami. Např. použijte import('./path/to/module.js') namísto import('@/module').

WARNING

vi.mock je hoistován (jinými slovy, přesunut) na začátek souboru. To znamená, že kdykoli ho napíšete (ať už uvnitř beforeEach nebo test), bude skutečně volán předtím.

To také znamená, že uvnitř factory nemůžete použít žádné proměnné, které jsou definovány mimo factory.

Pokud potřebujete použít proměnné uvnitř factory, zkuste vi.doMock. Funguje to stejně, ale není hoistováno. Mějte na paměti, že mockuje pouze následné importy.

Můžete také odkazovat na proměnné definované metodou vi.hoisted, pokud byla deklarována před vi.mock:

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

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

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

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

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

WARNING

Pokud mockujete modul s výchozím exportem, budete muset poskytnout klíč default v objektu vrácené factory funkce. Toto je specifická vlastnost pro moduly ES; proto se dokumentace jest může lišit, protože jest používá moduly CommonJS. Například:

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

Pokud existuje složka __mocks__ vedle souboru, který mockujete, a factory není poskytnuta, Vitest se pokusí najít soubor se stejným názvem v podsložce __mocks__ a použít jej jako skutečný modul. Pokud mockujete závislost, Vitest se pokusí najít složku __mocks__ v kořeni projektu (výchozí je process.cwd()). Vitestu můžete sdělit, kde se závislosti nacházejí, pomocí konfigurační možnosti deps.moduleDirectories.

Například máte tuto strukturu souborů:

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

Pokud zavoláte vi.mock v testovacím souboru bez poskytnuté factory nebo možností, najde soubor ve složce __mocks__, který bude použit jako modul:

ts
import { vi } from 'vitest';

// axios je výchozí export z `__mocks__/axios.js`
import axios from 'axios';

// increment je pojmenovaný export z `src/__mocks__/increment.js`
import { increment } from '../increment.js';

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

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

WARNING

Mějte na paměti, že pokud nezavoláte vi.mock, moduly nejsou mockovány automaticky. Chcete-li replikovat chování automockování Jestu, můžete zavolat vi.mock pro každý požadovaný modul uvnitř setupFiles.

Pokud neexistuje složka __mocks__ nebo není poskytnuta factory, Vitest importuje původní modul a automockuje všechny jeho exporty. Pravidla, která se použijí, naleznete v algoritmu.

vi.doMock ​

  • Typ: (path: string, factory?: MockOptions | ((importOriginal: () => unknown) => unknown)) => void
  • Typ: <T>(path: Promise<T>, factory?: MockOptions | ((importOriginal: () => T) => T | Promise<T>)) => void

Stejné jako vi.mock, ale není hoistováno na začátek souboru, takže můžete odkazovat na proměnné v globálním rozsahu souboru. Další dynamický import modulu bude mockován.

WARNING

Toto nebude mockovat moduly, které byly importovány předtím, než bylo toto voláno. Nezapomeňte, že všechny statické importy v ESM jsou vždy hoistovány, takže umístění tohoto před statický import nezpůsobí, že bude voláno před importem:

ts
vi.doMock('./increment.js'); // toto bude voláno _po_ příkazu import

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

// modul není mockován, protože vi.doMock ještě nebylo voláno
increment(1) === 2;

let mockedIncrement = 100;

beforeEach(() => {
  // můžete přistupovat k proměnným uvnitř factory
  vi.doMock('./increment.js', () => ({ increment: () => ++mockedIncrement }));
});

test('importování dalšího modulu importuje mockovaný modul', async () => {
  // původní import NEBYL MOCKOVÁN, protože vi.doMock je vyhodnoceno PO importech
  expect(increment(1)).toBe(2);
  const { increment: mockedIncrement } = await import('./increment.js');
  // nový dynamický import vrací mockovaný modul
  expect(mockedIncrement(1)).toBe(101);
  expect(mockedIncrement(1)).toBe(102);
  expect(mockedIncrement(1)).toBe(103);
});

vi.mocked ​

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

Pomocník typu pro TypeScript. Pouze vrátí předaný objekt.

Když je partial true, očekává Partial<T> jako návratovou hodnotu. Ve výchozím nastavení to způsobí, že TypeScript bude věřit, že jsou mockovány pouze hodnoty první úrovně. Můžete předat { deep: true } jako druhý argument, abyste TypeScriptu řekli, že je mockován celý objekt, pokud tomu tak skutečně je.

ts
export function add(x: number, y: number): number {
  return x + y;
}

export function fetchSomething(): Promise<Response> {
  return fetch('https://vitest.dev/');
}
ts
import * as example from './example';

vi.mock('./example');

test('1 + 1 se rovná 10', async () => {
  vi.mocked(example.add).mockReturnValue(10);
  expect(example.add(1, 1)).toBe(10);
});

test('mock návratová hodnota s pouze částečně správným typováním', async () => {
  vi.mocked(example.fetchSomething).mockResolvedValue(new Response('hello'));
  vi.mocked(example.fetchSomething, { partial: true }).mockResolvedValue({
    ok: false,
  });
  // vi.mocked(example.someFn).mockResolvedValue({ ok: false }) // toto je chyba typu
});

vi.importActual ​

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

Importuje modul, obchází všechny kontroly, zda by měl být mockován. Může být užitečné, pokud chcete modul mockovat částečně.

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

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

vi.importMock ​

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

Importuje modul se všemi jeho vlastnostmi (včetně vnořených vlastností) mockovanými. Řídí se stejnými pravidly jako vi.mock. Pravidla, která se použijí, naleznete v algoritmu.

vi.unmock ​

  • Typ: (path: string | Promise<Module>) => void

Odstraní modul z mockovaného registru. Všechna volání importu vrátí původní modul, i když byl předtím mockován. Toto volání je hoistováno na začátek souboru, takže odmockuje pouze moduly, které byly definovány například v setupFiles.

vi.doUnmock ​

  • Typ: (path: string | Promise<Module>) => void

Stejné jako vi.unmock, ale není hoistováno na začátek souboru. Další import modulu importuje původní modul namísto mocku. Toto neodmockuje dříve importované moduly.

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

// increment je již mockován, protože vi.mock je hoistováno
increment(1) === 100;

// toto je hoistováno a factory je volána před importem na řádku 1
vi.mock('./increment.js', () => ({ increment: () => 100 }));

// všechna volání jsou mockována a `increment` vždy vrací 100
increment(1) === 100;
increment(30) === 100;

// toto není hoistováno, takže jiný import vrátí neodmockovaný modul
vi.doUnmock('./increment.js');

// toto STÁLE vrací 100, protože `vi.doUnmock` nepřehodnocuje modul
increment(1) === 100;
increment(30) === 100;

// další import je neodmockován, nyní `increment` je původní funkce, která vrací count + 1
const { increment: unmockedIncrement } = await import('./increment.js');

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

vi.resetModules ​

  • Typ: () => Vitest

Resetuje registr modulů vymazáním cache všech modulů. To umožňuje opětovné vyhodnocení modulů při opětovném importu. Importy na nejvyšší úrovni nelze znovu vyhodnotit. Může být užitečné pro izolaci modulů, kde se lokální stav střetává mezi testy.

ts
import { vi } from 'vitest';

import { data } from './data.js'; // Nebude znovu vyhodnoceno před každým testem

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

test('změna stavu', async () => {
  const mod = await import('./some/path.js'); // Bude znovu vyhodnoceno
  mod.changeLocalState('new value');
  expect(mod.getLocalState()).toBe('new value');
});

test('modul má starý stav', async () => {
  const mod = await import('./some/path.js'); // Bude znovu vyhodnoceno
  expect(mod.getLocalState()).toBe('old value');
});

WARNING

Neresetuje registr mocků. Pro vymazání registru mocků použijte vi.unmock nebo vi.doUnmock.

vi.dynamicImportSettled ​

Počkejte, až se načtou všechny dynamické importy. Užitečné, pokud máte synchronní volání, které začne importovat modul, na jehož dokončení nelze jinak čekat.

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

// nelze sledovat import, protože Promise není vrácen
function renderComponent() {
  import('./component.js').then(({ render }) => {
    render();
  });
}

test('operace jsou vyřešeny', async () => {
  renderComponent();
  await vi.dynamicImportSettled();
  expect(document.querySelector('.component')).not.toBeNull();
});

TIP

Pokud se během dynamického importu spustí další dynamický import, tato metoda počká, dokud se všechny nevyřeší.

Tato metoda také počká na další setTimeout tick poté, co se import vyřeší, takže všechny synchronní operace by měly být dokončeny v době, kdy se vyřeší.

Mockování funkcí a objektů ​

Tato sekce popisuje, jak pracovat s mocky metod a nahrazovat proměnné prostředí a globální proměnné.

vi.fn ​

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

Vytvoří spy na funkci, i když může být inicializován bez ní. Pokaždé, když je funkce vyvolána, ukládá své argumenty volání, návratové hodnoty a instance. Také můžete manipulovat s jejím chováním pomocí metod. Pokud není zadána žádná funkce, mock vrátí undefined, když je vyvolán.

ts
const getApples = vi.fn(() => 0);

getApples();

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

getApples.mockReturnValueOnce(5);

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

vi.mockObject 3.2.0+ ​

  • Typ: <T>(value: T) => MaybeMockedDeep<T>

Hluboce mockuje vlastnosti a metody daného objektu stejným způsobem, jako vi.mock() mockuje exporty modulů. Podrobnosti viz automockování.

ts
const original = {
  simple: () => 'value',
  nested: {
    method: () => 'real',
  },
  prop: 'foo',
};

const mocked = vi.mockObject(original);
expect(mocked.simple()).toBe(undefined);
expect(mocked.nested.method()).toBe(undefined);
expect(mocked.prop).toBe('foo');

mocked.simple.mockReturnValue('mocked');
mocked.nested.method.mockReturnValue('mocked nested');

expect(mocked.simple()).toBe('mocked');
expect(mocked.nested.method()).toBe('mocked nested');

vi.isMockFunction ​

  • Typ: (fn: Function) => boolean

Zkontroluje, zda je daný parametr mockovací funkcí. Pokud používáte TypeScript, zúží také jeho typ.

vi.clearAllMocks ​

Volá .mockClear() na všech spyích. Tím se vymaže historie mocků bez ovlivnění implementace mocků.

vi.resetAllMocks ​

Volá .mockReset() na všech spyích. Tím se vymaže historie mocků a resetuje implementace každého mocku na původní.

vi.restoreAllMocks ​

Volá .mockRestore() na všech spyích. Tím se vymaže historie mocků, obnoví všechny původní implementace mocků a obnoví původní deskriptory spied-on objektů.

vi.spyOn ​

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

Vytvoří spy na metodu nebo getter/setter objektu podobně jako vi.fn(). Vrátí mockovací funkci.

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

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

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

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

TIP

V prostředích, která podporují Explicitní správu zdrojů, můžete použít using namísto const k automatickému volání mockRestore na jakékoli mockované funkci při opuštění obsahujícího bloku. To je obzvláště užitečné pro spied metody:

ts
it('volá console.log', () => {
  using spy = vi.spyOn(console, 'log').mockImplementation(() => {})
  debug('zpráva')
  expect(spy).toHaveBeenCalled()
})
// console.log je zde obnoven

TIP

Můžete zavolat vi.restoreAllMocks uvnitř afterEach (nebo povolit test.restoreMocks) pro obnovení všech metod na jejich původní implementace. Tím se obnoví původní deskriptor objektu, takže nebudete moci změnit implementaci metody:

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

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

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

TIP

Není možné spy na exportované metody v režimu prohlížeče. Místo toho můžete spy na každou exportovanou metodu voláním vi.mock("./file-path.js", { spy: true }). Tím se mockuje každý export, ale zachová se jeho implementace, což vám umožní ověřit, zda byla metoda správně volána.

ts
import { calculator } from './src/calculator.ts';

vi.mock('./src/calculator.ts', { spy: true });

calculator(1, 2);

expect(calculator).toHaveBeenCalledWith(1, 2);
expect(calculator).toHaveReturned(3);

A i když je možné spy na exporty v jsdom nebo jiných prostředích Node.js, toto se může v budoucnu změnit.

vi.stubEnv ​

  • Typ: <T extends string>(name: T, value: T extends "PROD" | "DEV" | "SSR" ? boolean : string | undefined) => Vitest

Změní hodnotu proměnné prostředí v process.env a import.meta.env. Její hodnotu můžete obnovit voláním vi.unstubAllEnvs.

ts
import { vi } from 'vitest';

// `process.env.NODE_ENV` a `import.meta.env.NODE_ENV`
// jsou "development" před voláním "vi.stubEnv"

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

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

vi.stubEnv('NODE_ENV', undefined);

process.env.NODE_ENV === undefined;
import.meta.env.NODE_ENV === undefined;

// nemění ostatní prostředí
import.meta.env.MODE === 'development';

TIP

Hodnotu můžete také změnit jednoduchým přiřazením, ale nebudete moci použít vi.unstubAllEnvs k obnovení předchozí hodnoty:

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

vi.unstubAllEnvs ​

  • Typ: () => Vitest

Obnoví všechny hodnoty import.meta.env a process.env, které byly změněny pomocí vi.stubEnv. Když je volána poprvé, Vitest si zapamatuje původní hodnotu a uloží ji, dokud nebude unstubAllEnvs znovu volána.

ts
import { vi } from 'vitest';

// `process.env.NODE_ENV` a `import.meta.env.NODE_ENV`
// jsou "development" před voláním stubEnv

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

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

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

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

vi.unstubAllEnvs();

// obnoví na hodnotu, která byla uložena před prvním voláním "stubEnv"
process.env.NODE_ENV === 'development';
import.meta.env.NODE_ENV === 'development';

vi.stubGlobal ​

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

Změní hodnotu globální proměnné. Její původní hodnotu můžete obnovit voláním vi.unstubAllGlobals.

ts
import { vi } from 'vitest';

// `innerWidth` je "0" před voláním stubGlobal

vi.stubGlobal('innerWidth', 100);

innerWidth === 100;
globalThis.innerWidth === 100;
// pokud používáte jsdom nebo happy-dom
window.innerWidth === 100;

TIP

Hodnotu můžete také změnit jednoduchým přiřazením k globalThis nebo window (pokud používáte prostředí jsdom nebo happy-dom), ale nebudete moci použít vi.unstubAllGlobals k obnovení původní hodnoty:

ts
globalThis.innerWidth = 100;
// pokud používáte jsdom nebo happy-dom
window.innerWidth = 100;

vi.unstubAllGlobals ​

  • Typ: () => Vitest

Obnoví všechny globální hodnoty na globalThis/global (a window/top/self/parent, pokud používáte prostředí jsdom nebo happy-dom), které byly změněny pomocí vi.stubGlobal. Když je volána poprvé, Vitest si zapamatuje původní hodnotu a uloží ji, dokud nebude unstubAllGlobals znovu volána.

ts
import { vi } from 'vitest';

const Mock = vi.fn();

// IntersectionObserver je "undefined" před voláním "stubGlobal"

vi.stubGlobal('IntersectionObserver', Mock);

IntersectionObserver === Mock;
global.IntersectionObserver === Mock;
globalThis.IntersectionObserver === Mock;
// pokud používáte jsdom nebo happy-dom
window.IntersectionObserver === Mock;

vi.unstubAllGlobals();

globalThis.IntersectionObserver === undefined;
'IntersectionObserver' in globalThis === false;
// vyhodí ReferenceError, protože není definováno
IntersectionObserver === undefined;

Falešné časovače ​

Tato sekce popisuje, jak pracovat s falešnými časovači.

vi.advanceTimersByTime ​

  • Typ: (ms: number) => Vitest

Tato metoda vyvolá každý inicializovaný časovač, dokud neuplyne zadaný počet milisekund nebo dokud není fronta prázdná – podle toho, co nastane dříve.

ts
let i = 0;
setInterval(() => console.log(++i), 50);

vi.advanceTimersByTime(150);

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

vi.advanceTimersByTimeAsync ​

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

Tato metoda vyvolá každý inicializovaný časovač, dokud neuplyne zadaný počet milisekund nebo dokud není fronta prázdná – podle toho, co nastane dříve. To bude zahrnovat asynchronně nastavené časovače.

ts
let i = 0;
setInterval(() => Promise.resolve().then(() => console.log(++i)), 50);

await vi.advanceTimersByTimeAsync(150);

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

vi.advanceTimersToNextTimer ​

  • Typ: () => Vitest

Zavolá další dostupný časovač. Užitečné pro provádění ověření mezi jednotlivými voláními časovače. Můžete jej řetězit a spravovat časovače sami.

ts
let i = 0;
setInterval(() => console.log(++i), 50);

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

vi.advanceTimersToNextTimerAsync ​

  • Typ: () => Promise<Vitest>

Zavolá další dostupný časovač a počká, dokud se nevyřeší, pokud byl nastaven asynchronně. Užitečné pro provádění ověření mezi jednotlivými voláními časovače.

ts
let i = 0;
setInterval(() => Promise.resolve().then(() => console.log(++i)), 50);

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

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

vi.advanceTimersToNextFrame 2.1.0+ ​

  • Typ: () => Vitest

Podobně jako vi.advanceTimersByTime, ale posune časovače o milisekundy potřebné k provedení zpětných volání aktuálně naplánovaných pomocí requestAnimationFrame.

ts
let frameRendered = false;

requestAnimationFrame(() => {
  frameRendered = true;
});

vi.advanceTimersToNextFrame();

expect(frameRendered).toBe(true);

vi.getTimerCount ​

  • Typ: () => number

Získá počet čekajících časovačů.

vi.clearAllTimers ​

Odstraní všechny časovače, které jsou naplánovány ke spuštění. Tyto časovače se v budoucnu nikdy nespustí.

vi.getMockedSystemTime ​

  • Typ: () => Date | null

Vrátí mockované aktuální datum. Pokud datum není mockováno, metoda vrátí null.

vi.getRealSystemTime ​

  • Typ: () => number

Při použití vi.useFakeTimers jsou volání Date.now mockována. Pokud potřebujete získat skutečný čas v milisekundách, můžete zavolat tuto funkci.

vi.runAllTicks ​

  • Typ: () => Vitest

Volá každou mikroúlohu, která byla zařazena do fronty pomocí process.nextTick. Tím se také spustí všechny mikroúlohy naplánované samy sebou.

vi.runAllTimers ​

  • Typ: () => Vitest

Tato metoda vyvolá každý inicializovaný časovač, dokud není fronta časovačů prázdná. To znamená, že každý časovač volaný během runAllTimers bude spuštěn. Pokud máte nekonečný interval, vyhodí chybu po 10 000 pokusech (lze konfigurovat pomocí fakeTimers.loopLimit).

ts
let i = 0;
setTimeout(() => console.log(++i));
const interval = setInterval(() => {
  console.log(++i);
  if (i === 3) {
    clearInterval(interval);
  }
}, 50);

vi.runAllTimers();

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

vi.runAllTimersAsync ​

  • Typ: () => Promise<Vitest>

Tato metoda asynchronně vyvolá každý inicializovaný časovač, dokud není fronta časovačů prázdná. To znamená, že každý časovač volaný během runAllTimersAsync bude spuštěn, dokonce i asynchronní časovače. Pokud máte nekonečný interval, vyhodí chybu po 10 000 pokusech (lze konfigurovat pomocí fakeTimers.loopLimit).

ts
setTimeout(async () => {
  console.log(await Promise.resolve('result'));
}, 100);

await vi.runAllTimersAsync();

// log: result

vi.runOnlyPendingTimers ​

  • Typ: () => Vitest

Tato metoda zavolá každý časovač, který byl inicializován po volání vi.useFakeTimers. Nebude spouštět žádný časovač, který byl inicializován během jejího volání.

ts
let i = 0;
setInterval(() => console.log(++i), 50);

vi.runOnlyPendingTimers();

// log: 1

vi.runOnlyPendingTimersAsync ​

  • Typ: () => Promise<Vitest>

Tato metoda asynchronně zavolá každý časovač, který byl inicializován po volání vi.useFakeTimers, dokonce i asynchronní. Nebude spouštět žádný časovač, který byl inicializován během jejího volání.

ts
setTimeout(() => {
  console.log(1);
}, 100);
setTimeout(() => {
  Promise.resolve().then(() => {
    console.log(2);
    setInterval(() => {
      console.log(3);
    }, 40);
  });
}, 10);

await vi.runOnlyPendingTimersAsync();

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

vi.setSystemTime ​

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

Pokud jsou povoleny falešné časovače, tato metoda simuluje, že uživatel mění systémové hodiny (ovlivní API související s datem, jako hrtime, performance.now nebo new Date()) – nicméně nespustí žádné časovače. Pokud falešné časovače nejsou povoleny, tato metoda bude mockovat pouze volání Date.*.

Užitečné, pokud potřebujete testovat cokoli, co závisí na aktuálním datu – například volání Luxon ve vašem kódu.

Přijímá stejné řetězcové a číselné argumenty jako Date.

ts
const date = new Date(1998, 11, 19);

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

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

vi.useRealTimers();

vi.useFakeTimers ​

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

Pro povolení mockování časovačů musíte zavolat tuto metodu. Obalí všechna další volání časovačů (jako setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, clearImmediate a Date), dokud není zavoláno vi.useRealTimers().

Mockování nextTick není podporováno při spouštění Vitestu uvnitř node:child_process pomocí --pool=forks. NodeJS interně používá process.nextTick v node:child_process a zamrzne, když je mockováno. Mockování nextTick je podporováno při spouštění Vitestu s --pool=threads.

Implementace je interně založena na @sinonjs/fake-timers.

TIP

vi.useFakeTimers() automaticky nemockuje process.nextTick a queueMicrotask. Můžete to však povolit zadáním možnosti v argumentu toFake: vi.useFakeTimers({ toFake: ['nextTick', 'queueMicrotask'] }).

vi.isFakeTimers ​

  • Typ: () => boolean

Vrátí true, pokud jsou povoleny falešné časovače.

vi.useRealTimers ​

  • Typ: () => Vitest

Když časovače doběhly, můžete zavolat tuto metodu, abyste vrátili mockované časovače k jejich původním implementacím. Všechny časovače, které byly naplánovány dříve, budou zahozeny.

Různé ​

Sada užitečných pomocných funkcí, které Vitest poskytuje.

vi.waitFor ​

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

Počká, dokud se zpětné volání úspěšně neprovede. Pokud zpětné volání vyhodí chybu nebo vrátí zamítnutý slib, bude pokračovat v čekání, dokud se nepodaří nebo nevyprší časový limit.

Pokud jsou možnosti nastaveny na číslo, je to ekvivalentní nastavení { timeout: options }.

To je velmi užitečné, když potřebujete počkat na dokončení nějaké asynchronní akce, například když spustíte server a potřebujete počkat, než se spustí.

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

test('Server se úspěšně spustil', async () => {
  const server = createServer();

  await vi.waitFor(
    () => {
      if (!server.isReady) {
        throw new Error('Server nebyl spuštěn');
      }

      console.log('Server spuštěn');
    },
    {
      timeout: 500, // výchozí je 1000
      interval: 20, // výchozí je 50
    }
  );
  expect(server.isReady).toBe(true);
});

Funguje to i pro asynchronní zpětná volání

ts
// @vitest-environment jsdom

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

test('Element existuje v DOM', async () => {
  // začít plnit DOM
  populateDOMAsync();

  const element = await vi.waitFor(
    async () => {
      // pokusit se získat element, dokud neexistuje
      const element = (await getDOMElementAsync()) as HTMLElement | null;
      expect(element).toBeTruthy();
      expect(element.dataset.initialized).toBeTruthy();
      return element;
    },
    {
      timeout: 500, // výchozí je 1000
      interval: 20, // výchozí je 50
    }
  );
  expect(element).toBeInstanceOf(HTMLElement);
});

Pokud je použito vi.useFakeTimers, vi.waitFor automaticky volá vi.advanceTimersByTime(interval) v každém zpětném volání kontroly.

vi.waitUntil ​

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

Toto je podobné vi.waitFor, ale pokud zpětné volání vyhodí jakékoli chyby, provádění je okamžitě přerušeno a je přijata chybová zpráva. Pokud zpětné volání vrátí hodnotu vyhodnocenou jako false, další kontrola bude pokračovat, dokud nebude vrácena hodnota vyhodnocená jako true. To je užitečné, když potřebujete počkat, než něco existuje, než podniknete další krok.

Podívejte se na příklad níže. Můžeme použít vi.waitUntil k čekání, než se element objeví na stránce, a pak s elementem něco udělat.

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

test('Element se vykreslí správně', async () => {
  const element = await vi.waitUntil(() => document.querySelector('.element'), {
    timeout: 500, // výchozí je 1000
    interval: 20, // výchozí je 50
  });

  // něco s elementem udělat
  expect(element.querySelector('.element-child')).toBeTruthy();
});

vi.hoisted ​

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

Všechny statické příkazy import v modulech ES jsou hoistovány na začátek souboru, takže jakýkoli kód, který je definován před importy, bude ve skutečnosti proveden po vyhodnocení importů.

Může však být užitečné vyvolat některé vedlejší efekty, jako je mockování dat před importem modulu.

Chcete-li toto omezení obejít, můžete statické importy přepsat na dynamické takto:

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

Při spouštění vitest to můžete provést automaticky pomocí metody vi.hoisted. Pod kapotou Vitest převede statické importy na dynamické s zachovanými živými vazbami.

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

IMPORTY NEJSOU DOSTUPNÉ

Spuštění kódu před importy znamená, že nemůžete přistupovat k importovaným proměnným, protože ještě nejsou definovány:

ts
import { value } from './some/module.js';

vi.hoisted(() => { value }); // vyhodí chybu

Tento kód vygeneruje chybu:

Nelze přistupovat k '__vi_import_0__' před inicializací

Pokud potřebujete přistupovat k proměnné z jiného modulu uvnitř vi.hoisted, použijte dynamický import:

ts
await vi.hoisted(async () => {
  const { value } = await import('./some/module.js');
});

Nicméně, nedoporučuje se importovat cokoli uvnitř vi.hoisted, protože importy jsou již hoistovány – pokud potřebujete něco spustit před spuštěním testů, stačí to spustit v samotném importovaném modulu.

Tato metoda vrací hodnotu, která byla vrácena z factory. Tuto hodnotu můžete použít ve svých vi.mock factories, pokud potřebujete snadný přístup k lokálně definovaným proměnným:

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

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

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

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

Všimněte si, že tato metoda může být volána asynchronně, i když vaše prostředí nepodporuje top-level await:

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

vi.setConfig ​

  • Typ: RuntimeConfig

Aktualizuje konfiguraci pro aktuální testovací soubor. Tato metoda podporuje pouze možnosti konfigurace, které ovlivní aktuální testovací soubor:

ts
vi.setConfig({
  allowOnly: true,
  testTimeout: 10_000,
  hookTimeout: 10_000,
  clearMocks: true,
  restoreMocks: true,
  fakeTimers: {
    now: new Date(2021, 11, 19),
    // podporuje celý objekt
  },
  maxConcurrency: 10,
  sequence: {
    hooks: 'stack',
    // podporuje pouze "sequence.hooks"
  },
});

vi.resetConfig ​

  • Typ: RuntimeConfig

Pokud bylo dříve voláno vi.setConfig, toto resetuje konfiguraci do původního stavu.

Pager
Předchozí stránkaMockovací funkce
Další stránkaexpect

Vydáno pod licencí MIT.

Copyright (c) 2021-Present Vitest Team

https://vitest.dev/api/vi

Vydáno pod licencí MIT.

Copyright (c) 2021-Present Vitest Team