Skip to content
Vitest 2
Main Navigation PrůvodceAPIKonfiguraceRežim prohlížečePokročilý
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

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

Mock funkce

Vi

expect

expectTypeOf

assert

assertType

Na této stránce

Vi ​

Vitest poskytuje užitečné funkce prostřednictvím svého nástroje vi. Můžete k němu přistupovat globálně (pokud je povolena konfigurace globals), 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í modulu. Pamatujte, ž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 dané cesty jiným modulem. V cestě můžete použít nakonfigurované Vite aliasy. Volání vi.mock je vyzdviženo (hoisted), takže nezáleží na tom, kde ho zavoláte. Vždy se provede 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 vyzdvihnout, Vitest staticky analyzuje vaše soubory. To znamená, že nelze použít vi, které nebylo přímo importováno z modulu vitest (například z nějakého pomocného souboru). 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ř setup souboru, protože jsou v době spuštění testovacího souboru již cachované. Můžete zavolat vi.resetModules() uvnitř vi.hoisted pro vymazání všech mezipamětí modulů před spuštěním testovacího souboru.

Pokud je definována funkce factory, všechny importy daného modulu 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ř.

Od Vitest 2.1 můžete místo factory funkce poskytnout také objekt s vlastností spy. Pokud je spy true, 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 slib modulu mí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čemž exporty zůstanou volitelné).

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(),
  };
});

Vnitřně 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ě rozlišit typy importů. Aby to fungovalo, ujistěte se, že nahradíte všechny aliasované importy odpovídajícími relativními cestami. Např. použijte import('./path/to/module.js') místo import('@/module').

WARNING

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

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

Pokud potřebujete použít proměnné uvnitř factory, zkuste vi.doMock. Funguje stejně, ale není přesunut nahoru. 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ém factory funkcí. Toto je specifické 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__. Tento soubor bude použit jako skutečný modul. Pokud mockujete závislost, Vitest se pokusí najít složku __mocks__ v kořenovém adresáři 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ý použije jako modul:

ts
// increment.test.js
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 automaticky mockovány. Chcete-li replikovat chování automockování Jest, můžete zavolat vi.mock pro každý modul, který chcete mockovat, uvnitř setupFiles.

Pokud neexistuje složka __mocks__ nebo není poskytnuta factory, Vitest importuje původní modul a automaticky mockuje 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í přesunuto 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ání provedeno. Nezapomeňte, že všechny statické importní příkazy v ESM jsou vždy přesunuty nahoru, takže umístění tohoto před statický import nezajistí, ž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
// ./increment.js
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ě není 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('importing the next module imports mocked one', 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ý typ pro TypeScript. Pouze vrací objekt, který byl předán.

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

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

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

vi.mock('./example');

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

test('mock return value with only partially correct typing', 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 mockovat modul částečně.

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

  return { ...axios, 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 registru mockovaných modulů. Všechna volání importu vrátí původní modul, i když byl předtím mockován. Toto volání je přesunuto 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í přesunuto na začátek souboru. Další import modulu importuje původní modul místo mocku. Toto neodmockuje dříve importované moduly.

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

// increment je již mockován, protože vi.mock je přesunuto nahoru
increment(1) === 100;

// toto je přesunuto nahoru 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í přesunuto nahoru, 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 modulům být znovu vyhodnoceny při opětovném importu. Importy na nejvyšší úrovni nelze znovu vyhodnotit. Může být užitečné pro izolaci modulů, kde lokální stav koliduje mezi testy.

ts
import { vi } from 'vitest';

import { data } from './data.js'; // Nebude znovu vyhodnoceno beforeEach test

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

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

test('module has old state', 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čká na načtení všech importů. Užitečné, pokud máte synchronní volání, které začne importovat modul, na který jinak nemůžete č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('operations are resolved', async () => {
  renderComponent();
  await vi.dynamicImportSettled();
  expect(document.querySelector('.component')).not.toBeNull();
});

TIP

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

Tato metoda také počká na další tick setTimeout po vyřešení importu, 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ří sledování funkce (spy), 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 kontext (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.isMockFunction ​

  • Typ: (fn: Function) => boolean

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

vi.clearAllMocks ​

Zavolá .mockClear() na všechny mockovací funkce. Tím se vymaže historie mocku, ale neresetuje se jeho implementace na výchozí.

vi.resetAllMocks ​

Zavolá .mockReset() na všechny mockovací funkce. Tím se vymaže historie mocku a resetuje se jeho implementace na prázdnou funkci (vrátí undefined).

vi.restoreAllMocks ​

Zavolá .mockRestore() na všechny mockovací funkce. Tím se vymaže historie mocku a resetuje se jeho implementace na původní.

vi.spyOn ​

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

Vytvoří sledování metody 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

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í popisovač vlastnosti 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é sledovat exportované metody v režimu prohlížeče. Místo toho můžete sledovat každou exportovanou metodu voláním vi.mock("./file-path.js", { spy: true }). Tím se mockuje každý export, ale zachová se jejich původní 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é sledovat exporty v jsdom nebo jiných prostředích Node.js, v budoucnu se to může 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í na 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í jiné envs
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áno poprvé, Vitest si zapamatuje původní hodnotu a uloží ji, dokud není unstubAllEnvs znovu voláno.

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áno poprvé, Vitest si zapamatuje původní hodnotu a uloží ji, dokud není unstubAllGlobals znovu voláno.

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 spustí každý iniciovaný č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 spustí každý iniciovaný časovač, dokud neuplyne zadaný počet milisekund nebo dokud není fronta prázdná - podle toho, co nastane dříve. To zahrnuje 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

Spustí další dostupný časovač. Užitečné pro provádění ověření mezi každým spuštěním č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>

Spustí další dostupný časovač a počká, dokud se nevyřeší, pokud byl nastaven asynchronně. Užitečné pro provádění ověření mezi každým spuštěním č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í funkcí zpětného 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, které bylo nastaveno pomocí setSystemTime. 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

Spustí každou mikrotasku, která byla zařazena do fronty pomocí process.nextTick. Tím se také spustí všechny mikrotasky naplánované samy sebou.

vi.runAllTimers ​

  • Typ: () => Vitest

Tato metoda spustí každý iniciovaný časovač, dokud není fronta časovačů prázdná. To znamená, že každý časovač naplánovaný během provádění 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ě spustí každý iniciovaný časovač, dokud není fronta časovačů prázdná. To znamená, že každý časovač naplánovaný během provádění 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 spustí každý časovač, který byl iniciován po volání vi.useFakeTimers. Nebude spouštět žádný časovač, který byl iniciová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ě spustí každý časovač, který byl iniciován po volání vi.useFakeTimers, dokonce i asynchronní. Nebude spouštět žádný časovač, který byl iniciová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 změnu systémových hodin uživatelem. Ovlivní API související s datem, jako je hrtime, performance.now nebo new Date(), ale nespustí žádné časovače. Pokud falešné časovače nejsou povoleny, tato metoda pouze mockuje 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é argumenty typu string a number 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. Přesměruje 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 spuštění Vitest uvnitř node:child_process pomocí --pool=forks. NodeJS interně používá process.nextTick v node:child_process a zablokuje se, když je mockován. Mockování nextTick je podporováno při spuštění Vitest s --pool=threads.

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

TIP

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

vi.isFakeTimers ​

  • Typ: () => boolean

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

vi.useRealTimers ​

  • Typ: () => Vitest

Když časovače doběhnou, můžete zavolat tuto metodu pro vrácení mockovaných časovačů na jejich původní implementace. Všechny časovače, které byly naplánovány dříve, budou zrušeny.

Různé ​

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

vi.waitFor ​

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

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

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 started successfully', async () => {
  const server = createServer();

  await vi.waitFor(
    () => {
      if (!server.isReady) {
        throw new Error('Server not started');
      }

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

Funguje také s asynchronními zpětnými voláními

ts
// @vitest-environment jsdom

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

test('Element exists in a DOM', async () => {
  // začít plnit DOM
  populateDOMAsync();

  const element = await vi.waitFor(
    async () => {
      // zkusit 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) při každém zpětném volání kontroly.

vi.waitUntil ​

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

Toto funguje podobně jako 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í nepravdivou hodnotu, další kontrola bude pokračovat, dokud nebude vrácena pravdivá hodnota. 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í na zobrazení prvku na stránce a poté s prvkem něco udělat.

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

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

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

vi.hoisted ​

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

Všechny statické importní příkazy v modulech ES jsou přesunuty 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ů.

Nicméně může být užitečné provést některé vedlejší efekty, například mockování dat, před importem modulu.

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

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

Při spuštění vitest to můžete provést automaticky pomocí metody vi.hoisted.

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

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 tuto metodu lze volat i asynchronně, i když vaše prostředí nepodporuje top-level await:

ts
const promised = 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 konfigurační možnosti, 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 předtím voláno vi.setConfig, tato metoda resetuje konfiguraci na původní stav.

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

Vydáno pod licencí MIT.

Copyright (c) 2024 Mithril Contributors

https://v2.vitest.dev/api/vi

Vydáno pod licencí MIT.

Copyright (c) 2024 Mithril Contributors