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

Vi ​

Vitest poskytuje užitečné funkce, které vám pomohou prostřednictvím svého pomocníka 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í modulů. Upozorňujeme, že Vitest nepodporuje mockování modulů, které byly importovány pomocí require().

vi.mock ​

  • Typ: (path: string, factory?: (importOriginal: () => unknown) => unknown) => void

Nahradí všechny importy z modulu na cestě path jiným modulem. Uvnitř cesty můžete použít nakonfigurované aliasy Vite. Volání vi.mock je přesunuto nahoru, takže nezáleží na tom, kde jej voláte. Vždy bude provedeno před všemi importy. Pokud potřebujete odkazovat na proměnné mimo jeho rozsah, můžete je definovat uvnitř vi.hoisted a odkazovat se na ně uvnitř vi.mock.

WARNING

vi.mock funguje pouze pro moduly, které byly importovány pomocí klíčového slova import. Nefunguje s require.

Aby bylo možné vi.mock přesunout nahoru, Vitest staticky analyzuje vaše soubory. To znamená, že nemůžete použít vi, které není přímo importováno z balíčku 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 uloženy v mezipaměti v době, kdy je spuštěn testovací soubor. Můžete zavolat vi.resetModules() uvnitř vi.hoisted a vymazat všechny mezipaměti modulů před spuštěním testovacího souboru.

WARNING

Režim prohlížeče v současné době nepodporuje mockování modulů. Tuto funkci můžete sledovat v GitHub issue.

Pokud je factory definována, všechny importy vrátí její výsledek. Vitest volá factory pouze jednou a ukládá výsledky do mezipaměti pro všechny následující importy, dokud není volána vi.unmock nebo vi.doUnmock.

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

js
import { vi } from 'vitest';
// ---cut---
// při použití JavaScriptu

vi.mock('./path/to/module.js', async importOriginal => {
  const mod = await importOriginal();
  return {
    ...mod,
    // nahradí některé exporty
    namedExport: vi.fn(),
  };
});
ts
// při použití TypeScriptu

vi.mock('./path/to/module.js', async importOriginal => {
  const mod = await importOriginal<typeof import('./path/to/module.js')>();
  return {
    ...mod,
    // nahradí některé exporty
    namedExport: vi.fn(),
  };
});

WARNING

vi.mock je přesunuto (jinými slovy, přesunuto) na začátek souboru. To znamená, že bez ohledu na to, kam jej umístíte (do beforeEach nebo test), bude vždy vyvoláno dříve.

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

Pokud potřebujete použít proměnné uvnitř factory, zkuste vi.doMock. Funguje to stejně, ale není to přesunuto nahoru. Upozorňujeme, že mockuje pouze následující 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 zadat klíč default v rámci vráceného objektu factory funkce. Toto je specifický rys ES modulů; 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 vedle souboru, který mockujete, existuje složka __mocks__ a není zadána žádná factory, 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()). Můžete říct Vitestu, kde se nacházejí závislosti, prostřednictvím 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 v testovacím souboru zavoláte vi.mock bez poskytnuté factory, najde soubor ve složce __mocks__, který se 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

Pozor, pokud nezavoláte vi.mock, moduly nebudou automaticky mockovány. Chcete-li replikovat chování automatického mockování Jestu, můžete zavolat vi.mock pro každý požadovaný modul uvnitř setupFiles.

Pokud neexistuje složka __mocks__ nebo poskytnutá factory, Vitest importuje původní modul a automaticky mockuje všechny jeho exporty. Pro použitá pravidla viz algoritmus.

vi.doMock ​

  • Typ: (path: string, factory?: (importOriginal: () => unknown) => unknown) => 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 oboru. Další dynamický import modulu bude mockován.

WARNING

Toto nebude mockovat moduly, které byly importovány před tímto voláním. Nezapomeňte, že všechny statické importy v ESM jsou vždy přesunuty nahoru, takže umístění tohoto před statický import jej nenutí, aby byl volán 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ě nebyl volán
increment(1) === 2;

let mockedIncrement = 100;

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

test('import dalšího modulu importuje mockovaný modul', async () => {
  // původní import NEBYL MOCKOVÁN, protože vi.doMock je vyhodnocen 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 pro typy pro TypeScript. Vrací objekt, který byl předán.

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 a říct TypeScriptu, že je mockován celý objekt, pokud tomu tak skutečně je.

ts
import example from './example.js';

vi.mock('./example.js');

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

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 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. Dodržuje stejná pravidla jako vi.mock. Pro použitá pravidla viz algoritmus.

vi.unmock ​

  • Typ: (path: string) => void

Odebere modul z mockovaného registru. Všechna volání importu vrátí původní modul, i když byl dříve mockován. Protože je toto volání přesunuto na začátek souboru, odmockuje pouze moduly, které byly definovány například v setupFiles.

vi.doUnmock ​

  • Typ: (path: string) => void

Stejné jako vi.unmock, ale není přesunuto na začátek souboru. Další import modulu importuje původní modul místo mocku. Toto nemá vliv na 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í odmockovaný 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 odmockován, nyní je `increment` 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ů tím, že vymaže jejich cache. To umožňuje přehodnocení modulů při opětovném importu. Importy nejvyšší úrovně nelze přehodnotit. Může být užitečné izolovat moduly, kde lokální stav způsobuje konflikty mezi testy.

ts
import { vi } from 'vitest';

import { data } from './data.js'; // Nebude přehodnoceno beforeEach test

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

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

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

WARNING

Neresetuje registr mocků. Chcete-li vymazat registr 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 který jinak nemůžete čekat.

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

// nelze sledovat import, protože Promise není vrácena
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 je během dynamického importu zahájen jiný dynamický import, tato metoda počká, dokud nebudou všechny vyřešeny.

Tato metoda také počká na další setTimeout tick po vyřešení importu, takže všechny synchronní operace by měly být dokončeny do doby, než bude vyřešen.

Mockování funkcí a objektů ​

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

vi.fn ​

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

Vytvoří spy pro funkci, nebo může být inicializován i bez ní. Pokaždé, když je funkce vyvolána, uloží 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
import { expect, vi } from 'vitest';
// ---cut---
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í funkce. Pokud používáte TypeScript, také zúží jeho typ.

vi.clearAllMocks ​

Zavolá .mockClear() na všechny špehy. Tím se vymaže historie volání mocků, ale implementace zůstane beze změny.

vi.resetAllMocks ​

Zavolá .mockReset() na všechny špehy. Tím se vymaže historie mocků a resetuje se její implementace na prázdnou funkci (vrátí undefined).

vi.restoreAllMocks ​

Zavolá .mockRestore() na všechny špehy. Tím se vymaže historie mocků a resetuje se její implementace na původní.

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(). Vrací mockovací funkci.

ts
import { expect, vi } from 'vitest';
// ---cut---
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), abyste obnovili všechny metody 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!

vi.stubEnv 0.26.0+ ​

  • Typ: (name: string, value: string) => Vitest

Nastaví hodnotu proměnné prostředí v process.env a import.meta.env. Můžete obnovit její hodnotu 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';
// nemění ostatní envs
import.meta.env.MODE === 'development';

TIP

Hodnotu lze také změnit přímý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 0.26.0+ ​

  • Typ: () => Vitest

Obnoví původní hodnoty v import.meta.env a process.env, které byly změněny pomocí vi.stubEnv. Při prvním volání si Vitest zapamatuje původní hodnotu a uloží ji, dokud není unstubAllEnvs zavolána znovu.

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í 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

Nastaví hodnotu globální proměnné. Můžete obnovit její původní hodnotu 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 lze také změnit jednoduše 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 0.26.0+ ​

  • 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. Při prvním volání si Vitest zapamatuje původní hodnotu a uloží ji, dokud není unstubAllGlobals zavolána znovu.

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;
// vyvolá ReferenceError, protože není definován
IntersectionObserver === undefined;

Fake Timers ​

Tato sekce popisuje, jak používat falešné časovače.

vi.advanceTimersByTime ​

  • Typ: (ms: number) => Vitest

Tato metoda posune čas ve všech spuštěných časovačích o zadaný počet milisekund, nebo dokud není fronta časovačů prázdná, podle toho, co nastane dříve.

ts
import { vi } from 'vitest';
// ---cut---
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 asynchronně posune čas ve všech spuštěných časovačích o zadaný počet milisekund, nebo dokud není fronta časovačů prázdná, podle toho, co nastane dříve. Zahrnuje i asynchronně nastavené časovače.

ts
import { vi } from 'vitest';
// ---cut---
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í nejbližší naplánovaný časovač. To je užitečné pro provádění kontrol mezi jednotlivými spuštěními časovačů. Můžete jej řetězit a spravovat časovače ručně.

ts
import { vi } from 'vitest';
// ---cut---
let i = 0;
setInterval(() => console.log(++i), 50);

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

vi.advanceTimersToNextTimerAsync ​

  • Typ: () => Promise<Vitest>

Spustí nejbližší naplánovaný časovač a počká na jeho dokončení, pokud byl nastaven asynchronně. Užitečné pro provádění kontrol mezi jednotlivými spuštěními časovače.

ts
import { expect, vi } from 'vitest';
// ---cut---
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.getTimerCount ​

  • Typ: () => number

Vrací počet aktuálně čekajících časovačů.

vi.clearAllTimers ​

Zruší všechny časovače, které jsou naplánované ke spuštění. Tyto časovače se již nikdy nespustí.

vi.getMockedSystemTime ​

  • Typ: () => Date | null

Vrací simulované aktuální datum, které bylo nastaveno pomocí setSystemTime. Pokud datum není simulované, metoda vrátí null.

vi.getRealSystemTime ​

  • Typ: () => number

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

vi.runAllTicks ​

  • Typ: () => Vitest

Spustí všechny mikrotasky zařazené do fronty pomocí process.nextTick. Tím se také spustí všechny mikrotasky naplánované těmito mikrotaskami.

vi.runAllTimers ​

  • Typ: () => Vitest

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

ts
import { vi } from 'vitest';
// ---cut---
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í všechny spuštěné časovače, dokud není fronta časovačů prázdná, včetně asynchronních časovačů. Pokud máte nekonečný interval, vyvolá výjimku po 10 000 pokusech (lze konfigurovat pomocí fakeTimers.loopLimit).

ts
import { vi } from 'vitest';
// ---cut---
setTimeout(async () => {
  console.log(await Promise.resolve('result'));
}, 100);

await vi.runAllTimersAsync();

// log: result

vi.runOnlyPendingTimers ​

  • Typ: () => Vitest

Tato metoda spustí pouze ty časovače, které byly naplánovány po volání vi.useFakeTimers. Nespustí žádný časovač spuštěný během tohoto volání.

ts
import { vi } from 'vitest';
// ---cut---
let i = 0;
setInterval(() => console.log(++i), 50);

vi.runOnlyPendingTimers();

// log: 1

vi.runOnlyPendingTimersAsync ​

  • Typ: () => Promise<Vitest>

Tato metoda asynchronně spustí pouze ty časovače, které byly naplánovány po volání vi.useFakeTimers, včetně asynchronních. Nespustí žádný časovač spuštěný během tohoto volání.

ts
import { vi } from 'vitest';
// ---cut---
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ého času uživatelem (ovlivní API související s datem, jako je hrtime, performance.now nebo new Date()) - nicméně nespustí žádné časovače. Pokud falešné časovače nejsou povoleny, tato metoda simuluje pouze volání Date.*.

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

ts
import { expect, vi } from 'vitest';
// ---cut---
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í simulace časovačů je nutné zavolat tuto metodu. Přesměruje všechna následující volání časovačů (jako setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, clearImmediate a Date) na falešné implementace, dokud není zavolána metoda vi.useRealTimers().

Mockování nextTick není podporováno při spuštění Vitest uvnitř node:child_process pomocí --pool=forks. NodeJS používá process.nextTick interně v node:child_process a při mockování dojde k zablokování. Simulace nextTick je podporována při spuštění Vitest s --pool=threads.

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

TIP

Od verze 0.35.0 vi.useFakeTimers() již automaticky nesimuluje process.nextTick. Stále jej lze simulovat zadáním možnosti v argumentu toFake: vi.useFakeTimers({ toFake: ['nextTick'] }).

vi.isFakeTimers 0.34.5+ ​

  • Typ: () => boolean

Vrací true, pokud jsou povoleny falešné časovače.

vi.useRealTimers ​

  • Typ: () => Vitest

Po použití falešných časovačů můžete zavolat tuto metodu a obnovit původní implementace časovačů. Všechny časovače, které byly naplánovány dříve, budou zrušeny.

Různé ​

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

vi.waitFor 0.34.5+ ​

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

Čeká, dokud se zpětné volání úspěšně neprovede. Pokud zpětné volání vyvolá chybu nebo vrátí odmítnutý slib, bude čekat, dokud se nepodaří nebo nevyprší časový limit.

To je velmi užitečné, když potřebujete počkat na dokončení asynchronní akce, například spuštění serveru.

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í hodnota je 1000
      interval: 20, // výchozí hodnota je 50
    }
  );
  expect(server.isReady).toBe(true);
});

Funguje to také pro asynchronní zpětná volání

ts
// @vitest-environment jsdom

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

test('Element exists in a DOM', async () => {
  // start populating DOM
  populateDOMAsync();

  const element = await vi.waitFor(
    async () => {
      // try to get the element until it exists
      const element = (await getDOMElementAsync()) as HTMLElement | null;
      expect(element).toBeTruthy();
      expect(element.dataset.initialized).toBeTruthy();
      return element;
    },
    {
      timeout: 500, // výchozí hodnota je 1000
      interval: 20, // výchozí hodnota je 50
    }
  );
  expect(element).toBeInstanceOf(HTMLElement);
});

Pokud je použito vi.useFakeTimers, vi.waitFor automaticky volá vi.advanceTimersByTime(interval) při každém spuštění zpětného volání.

vi.waitUntil 0.34.5+ ​

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

To je podobné jako vi.waitFor, ale pokud zpětné volání vyvolá nějaké chyby, provádění se okamžitě přeruší a obdrží se chybová zpráva. Pokud zpětné volání vrátí hodnotu vyhodnocenou jako false, další kontrola bude pokračovat, dokud se nevrátí hodnota vyhodnocená jako true. To je užitečné, když potřebujete počkat, až něco existuje, než provedete 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é můžeme 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í hodnota je 1000
    interval: 20, // výchozí hodnota je 50
  });

  // do something with the element
  expect(element.querySelector('.element-child')).toBeTruthy();
});

vi.hoisted 0.31.0+ ​

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

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

Může být užitečné vyvolat některé vedlejší účinky, například simulaci dat před importem modulu.

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

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

Při spuštění vitest to můžete udělat 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 továrny. Tuto hodnotu můžete použít ve svých továrnách vi.mock, 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 také volat asynchronně, i když vaše prostředí nepodporuje await nejvyšší úrovně:

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 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),
    // supports the whole object
  },
  maxConcurrency: 10,
  sequence: {
    hooks: 'stack',
    // supports only "sequence.hooks"
  },
});

vi.resetConfig ​

  • Typ: RuntimeConfig

Pokud byla dříve volána funkce vi.setConfig, obnoví se tím původní konfigurace.

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

Vydáno pod licencí MIT.

Copyright (c) 2024 Mithril Contributors

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

Vydáno pod licencí MIT.

Copyright (c) 2024 Mithril Contributors