Skip to content
Vitest 3
Main Navigation Útmutató & APIKonfigurációBöngésző módHaladó API
3.2.0
2.1.9
1.6.1
0.34.6

magyar

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

magyar

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

Megjelenés

Sidebar Navigation

Bevezetés

Miért Vitest

Első lépések

Jellemzők

Vitest konfigurálása

API

Teszt API Referencia

Mock Függvények

Vi

expect

expectTypeOf

assert

assertType

Útmutató

Parancssori felület

Teszt szűrés

Tesztprojektek

Jelentéskészítők (Reporters)

Kódlefedettség

Snapshot

Mockolás

Párhuzamos végrehajtás

Típusok Tesztelése

Vitest UI

Forráskódba ágyazott tesztelés

Tesztkörnyezet

Teszt annotációk

Tesztkörnyezet

Matcherek kiterjesztése

IDE Integrációk

Hibakeresés

Gyakori hibák

Migrációs útmutató

Migrálás a Vitest 3.0-ra

Migrálás Jesstről

Teljesítmény

Teszt teljesítmény profilozása

Teljesítmény javítása

Böngésző üzemmód

Haladó API

Összehasonlítás más tesztfuttatókkal

Ezen az oldalon

Vi ​

A Vitest a vi segédfüggvényen keresztül biztosít segédprogramokat. Ezt globálisan is elérheti (ha a globals konfiguráció engedélyezve van), vagy közvetlenül importálhatja a vitest csomagból:

js
import { vi } from 'vitest';

Modulok Mockolása ​

Ez a szakasz az API-t írja le, amelyet modulok mockolásakor használhat. Fontos megjegyezni, hogy a Vitest nem támogatja a require()-ral importált modulok mockolását.

vi.mock ​

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

Az összes importált modult a megadott path útvonalról egy másik modullal helyettesíti. A konfigurált Vite aliasokat használhatja az útvonalon belül. A vi.mock hívás emelt (hoisted), így nem számít, hogy hol hívja meg. Mindig az összes importálás előtt hajtódik végre. Ha a hatókörén kívüli változókra szeretne hivatkozni, azokat a vi.hoisted belsejében definiálhatja, és hivatkozhat rájuk a vi.mock belsejében.

WARNING

A vi.mock csak az import kulcsszóval importált modulok esetén működik. A require esetén nem működik.

A vi.mock emeléséhez a Vitest statikusan elemzi a fájlokat. Ezért a vi nem használható, ha nem közvetlenül a vitest csomagból (például valamilyen segédprogram fájlból) importálták. Használja a vi.mock függvényt a vitest csomagból importált vi segítségével, vagy engedélyezze a globals konfigurációs opciót.

A Vitest nem fogja mockolni azokat a modulokat, amelyeket egy setup fájlban importáltak, mert azok már gyorsítótárazva vannak a tesztfájl futásakor. Hívhatja a vi.resetModules() függvényt a vi.hoisted belsejében, hogy törölje az összes modul gyorsítótárát a tesztfájl futtatása előtt.

Ha a factory függvény definiálva van, az összes importálás annak eredményét adja vissza. A Vitest csak egyszer hívja meg a factory-t, és gyorsítótárazza az eredményeket az összes további importáláshoz, amíg a vi.unmock vagy a vi.doUnmock meg nem hívódik.

A jest-től eltérően a factory aszinkron is lehet. Használhatja a vi.importActual függvényt, vagy egy segédprogramot, amelynek első argumentumaként a factory-t adja át, és így hozzáférhet az eredeti modulhoz.

A factory függvény helyett megadhat egy objektumot is, amelynek van egy spy tulajdonsága. Ha a spy értéke true, akkor a Vitest a szokásos módon automatikusan mockolja a modult, de nem írja felül az exportok implementációját. Ez akkor hasznos, ha csak azt szeretné ellenőrizni, hogy az exportált metódust egy másik metódus helyesen hívta-e meg.

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

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

// meghívja az eredeti implementációt,
// de lehetővé teszi a viselkedés későbbi ellenőrzését
const result = calculator(1, 2);

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

A Vitest támogatja a modul promise-t is a vi.mock és vi.doMock metódusokban string helyett a jobb IDE támogatás érdekében. Amikor a fájl áthelyezésre kerül, az útvonal frissül, és az importOriginal automatikusan örökli a típust. Ennek a szignatúrának a használata azt is biztosítja, hogy a factory visszatérési típusa kompatibilis legyen az eredeti modullal (az exportok opcionálisak maradnak).

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(); // a típus kikövetkeztetett
  //    ^?
  return {
    ...mod,
    // néhány export felülírása
    total: vi.fn(),
  };
});

A háttérben a Vitest továbbra is stringgel, nem pedig modulobjektummal dolgozik.

Ha azonban TypeScriptet használ a tsconfig.json fájlban konfigurált paths aliasokkal, a fordító nem fogja tudni helyesen feloldani az import típusokat. Ahhoz, hogy ez működjön, győződjön meg róla, hogy az összes aliased importot lecseréli a megfelelő relatív útvonalakra. Pl. használja az import('./path/to/module.js') helyett az import('@/module') kifejezést.

WARNING

A vi.mock emelt (más szóval, áthelyezett) a fájl tetejére. Ez azt jelenti, hogy bárhol is írja (legyen az beforeEach vagy test belsejében), az valójában előbb hajtódik végre.

Ez azt is jelenti, hogy a factory belsejében nem használhat olyan változókat, amelyek a factoryn kívül vannak definiálva.

Ha változókat szeretne használni a factory belsejében, próbálja meg a vi.doMock függvényt. Ugyanúgy működik, de nem emelt. Fontos megjegyezni, hogy csak a későbbi importokat mockolja.

Hivatkozhat a vi.hoisted metódussal definiált változókra is, ha az a vi.mock előtt lett deklarálva:

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

Ha egy modult alapértelmezett exporttal mockol, akkor a visszaadott factory függvény objektumon belül meg kell adnia egy default kulcsot. Ez egy ES modul-specifikus sajátosság; ezért a jest dokumentációja eltérhet, mivel a jest CommonJS modulokat használ. Például:

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

Ha van egy __mocks__ mappa a mockolt fájl mellett, és a factory nincs megadva, a Vitest megpróbálja megtalálni a __mocks__ almappában az azonos nevű fájlt, és azt használja tényleges modulként. Ha egy függőséget mockol, a Vitest megpróbálja megtalálni a __mocks__ mappát a projekt gyökerében (alapértelmezés szerint process.cwd()). A Vitestnek megadhatja, hol találhatók a függőségek a deps.moduleDirectories konfigurációs opcióval.

Például, van ez a fájlstruktúra:

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

Ha a vi.mock függvényt egy tesztfájlban factory vagy opciók nélkül hívja meg, akkor a __mocks__ mappában keres egy fájlt, amelyet modulként használhat:

ts
import { vi } from 'vitest';

// az axios egy alapértelmezett export a `__mocks__/axios.js` fájlból
import axios from 'axios';

// az increment egy elnevezett export a `src/__mocks__/increment.js` fájlból
import { increment } from '../increment.js';

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

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

WARNING

Ne feledje, hogy ha nem hívja meg a vi.mock függvényt, a modulok nem lesznek automatikusan mockolva. A Jest automocking viselkedésének utánzásához meghívhatja a vi.mock függvényt minden szükséges modulhoz a setupFiles belsejében.

Ha nincs __mocks__ mappa vagy megadott factory, a Vitest importálja az eredeti modult, és automatikusan mockolja az összes exportját. Az alkalmazott szabályokat lásd az algoritmus részben.

vi.doMock ​

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

Ugyanaz, mint a vi.mock, de nem emelkedik fel a fájl tetejére, így hivatkozhat a globális fájlhatókörben lévő változókra. A modul következő dinamikus importálása mockolt lesz.

WARNING

Ez nem fogja mockolni azokat a modulokat, amelyeket ezen hívás előtt importáltak. Fontos megjegyezni, hogy az ESM-ben az összes statikus import mindig emelt, így ennek a statikus import elé helyezése nem fogja biztosítani, hogy az import előtt hívják meg:

ts
vi.doMock('./increment.js'); // ez az import utasítás _után_ fog meghívódni

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

// a modul nincs mockolva, mert a vi.doMock még nincs meghívva
increment(1) === 2;

let mockedIncrement = 100;

beforeEach(() => {
  // hozzáférhet a változókhoz a factory belsejében
  vi.doMock('./increment.js', () => ({ increment: () => ++mockedIncrement }));
});

test('a következő modul importálása a mockoltat importálja', async () => {
  // az eredeti import NEM VOLT MOCKOLVA, mert a vi.doMock az importok UTÁN értékelődik ki
  expect(increment(1)).toBe(2);
  const { increment: mockedIncrement } = await import('./increment.js');
  // az új dinamikus import mockolt modult ad vissza
  expect(mockedIncrement(1)).toBe(101);
  expect(mockedIncrement(1)).toBe(102);
  expect(mockedIncrement(1)).toBe(103);
});

vi.mocked ​

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

Típussegéd a TypeScript számára. Az átadott objektumot adja vissza.

Ha a partial értéke true, akkor Partial<T>-t vár visszatérési értékként. Alapértelmezés szerint ez csak azt jelzi a TypeScriptnek, hogy az első szintű értékek mockolva vannak. Átadhatja a { deep: true } értéket második argumentumként, hogy elmondja a TypeScriptnek, hogy az egész objektum mockolva van, ha az valóban az.

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 egyenlő 10-zel', async () => {
  vi.mocked(example.add).mockReturnValue(10);
  expect(example.add(1, 1)).toBe(10);
});

test('mock visszatérési érték csak részben helyes típusozással', 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 }) // ez típus hiba
});

vi.importActual ​

  • Típus: <T>(path: string) => Promise<T>

Modult importál, megkerülve az összes ellenőrzést, hogy mockolni szükséges-e. Hasznos lehet, ha részlegesen szeretné mockolni a modult.

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

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

vi.importMock ​

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

Egy modult importál az összes tulajdonságával (beleértve a beágyazott tulajdonságokat is) mockolva. Ugyanazokat a szabályokat követi, mint a vi.mock. Az alkalmazott szabályokat lásd az algoritmus részben.

vi.unmock ​

  • Típus: (path: string | Promise<Module>) => void

Eltávolítja a modult a mockolt regiszterből. Az összes importálás az eredeti modult adja vissza, még akkor is, ha korábban mockolták. Ez a hívás a fájl tetejére emelkedik, így csak azokat a modulokat fogja unmockolni, amelyek például a setupFiles fájlokban lettek definiálva.

vi.doUnmock ​

  • Típus: (path: string | Promise<Module>) => void

Ugyanaz, mint a vi.unmock, de nem emelkedik fel a fájl tetejére. A modul következő importálása az eredeti modult fogja importálni a mock helyett. Ez nem fogja visszaállítani a korábban importált modulokat.

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

// az increment már mockolva van, mert a vi.mock felemelt
increment(1) === 100;

// ez emelt, és a factory az 1. sorban lévő import előtt hívódik meg
vi.mock('./increment.js', () => ({ increment: () => 100 }));

// az összes hívás mockolva van, és az `increment` mindig 100-at ad vissza
increment(1) === 100;
increment(30) === 100;

// ez nincs emelve, így a másik import unmockolt modult ad vissza
vi.doUnmock('./increment.js');

// ez MÉG MINDIG 100-at ad vissza, mert a `vi.doUnmock` nem értékeli újra a modult
increment(1) === 100;
increment(30) === 100;

// a következő import unmockolt, most az `increment` az eredeti függvény, amely a count + 1-et adja vissza
const { increment: unmockedIncrement } = await import('./increment.js');

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

vi.resetModules ​

  • Típus: () => Vitest

Visszaállítja a modulok nyilvántartását az összes modul gyorsítótárának törlésével. Ez lehetővé teszi a modulok újraértékelését az újraimportáláskor. A legfelső szintű importok nem értékelhetők újra. Hasznos lehet a modulok izolálására, ahol a helyi állapot ütközéseket okoz a tesztek között.

ts
import { vi } from 'vitest';

import { data } from './data.js'; // Nem fog újraértékelődni minden teszt előtt

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

test('állapot megváltoztatása', async () => {
  const mod = await import('./some/path.js'); // Újraértékelődik
  mod.changeLocalState('new value');
  expect(mod.getLocalState()).toBe('new value');
});

test('a modul régi állapotban van', async () => {
  const mod = await import('./some/path.js'); // Újraértékelődik
  expect(mod.getLocalState()).toBe('old value');
});

WARNING

Nem állítja vissza a mock nyilvántartást. A mock nyilvántartás törléséhez használja a vi.unmock vagy a vi.doUnmock függvényt.

vi.dynamicImportSettled ​

Megvárja az összes import betöltését. Hasznos, ha van egy szinkron hívása, amely egy modult kezd importálni, és azt egyébként nem tudná megvárni.

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

// nem tudja nyomon követni az importot, mert a Promise nem kerül visszaadásra
function renderComponent() {
  import('./component.js').then(({ render }) => {
    render();
  });
}

test('a műveletek feloldódtak', async () => {
  renderComponent();
  await vi.dynamicImportSettled();
  expect(document.querySelector('.component')).not.toBeNull();
});

TIP

Ha egy dinamikus import során egy másik dinamikus import is elindul, ez a metódus megvárja, amíg mindegyik feloldódik.

Ez a metódus megvárja a következő setTimeout ütemet is, miután az import feloldódott, így az összes szinkron műveletnek be kell fejeződnie, mire feloldódik.

Függvények és objektumok mockolása ​

Ez a szakasz leírja, hogyan kell dolgozni a metódus mockokkal, és hogyan kell felülírni a környezeti és globális változókat.

vi.fn ​

  • Típus: (fn?: Function) => Mock

Kémfüggvényt hoz létre egy függvényhez, bár anélkül is inicializálható. Minden alkalommal, amikor egy függvényt meghívnak, tárolja a hívási argumentumait, visszatérési értékeit és a példányokat. Emellett manipulálhatja a viselkedését metódusokkal. Ha nincs megadva függvény, a mock undefined értéket ad vissza, ha meghívják.

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+ ​

  • Típus: <T>(value: T) => MaybeMockedDeep<T>

Mélyen mockolja egy adott objektum tulajdonságait és metódusait ugyanúgy, ahogy a vi.mock() a modul exportokat mockolja. Részletekért lásd az automockingot.

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 ​

  • Típus: (fn: Function) => boolean

Ellenőrzi, hogy egy adott paraméter mock függvény. Ha TypeScriptet használ, akkor a típusát is pontosítja.

vi.clearAllMocks ​

Meghívja a .mockClear() függvényt az összes kémobjektumon. Ez törli a mock előzményeket anélkül, hogy érintené a mock implementációkat.

vi.resetAllMocks ​

Meghívja a .mockReset() függvényt az összes kémobjektumon. Ez törli a mock előzményeket, és visszaállítja az egyes mockok implementációját az eredeti állapotába.

vi.restoreAllMocks ​

Meghívja a .mockRestore() függvényt az összes kémobjektumon. Ez törli a mock előzményeket, visszaállítja az összes eredeti mock implementációt, és visszaállítja a megfigyelt objektumok eredeti leíróit.

vi.spyOn ​

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

Kémfüggvényt hoz létre egy objektum metódusához vagy getter/setteréhez, hasonlóan a vi.fn() függvényhez. Egy mock függvényt ad vissza.

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

Azokban a környezetekben, amelyek támogatják az Explicit Resource Management mechanizmust, használhatja a using kulcsszót a const helyett, hogy automatikusan meghívja a mockRestore függvényt bármely mockolt függvényen, amikor a tartalmazó blokk kilép. Ez különösen hasznos a megfigyelt metódusok esetében:

ts
it('calls console.log', () => {
  using spy = vi.spyOn(console, 'log').mockImplementation(() => {})
  debug('message')
  expect(spy).toHaveBeenCalled()
})
// console.log is restored here

TIP

Meghívhatja a vi.restoreAllMocks függvényt az afterEach belsejében (vagy engedélyezheti a test.restoreMocks opciót), hogy az összes metódust visszaállítsa az eredeti implementációjára. Ez visszaállítja az eredeti objektum leírót, így nem fogja tudni megváltoztatni a metódus implementációját:

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()); // még mindig 42!

TIP

Nem lehetséges megfigyelni az exportált metódusokat Böngésző módban. Ehelyett kémkedhet minden exportált metóduson a vi.mock("./file-path.js", { spy: true }) meghívásával. Ez minden exportot mockol, de az implementációját változatlanul hagyja, lehetővé téve, hogy ellenőrizze, hogy a metódust helyesen hívták-e meg.

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

És bár lehetséges kémkedni az exportokon jsdom vagy más Node.js környezetekben, ez a jövőben változhat.

vi.stubEnv ​

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

Megváltoztatja a környezeti változó értékét a process.env és import.meta.env objektumokon. Az értékét visszaállíthatja a vi.unstubAllEnvs meghívásával.

ts
import { vi } from 'vitest';

// `process.env.NODE_ENV` és `import.meta.env.NODE_ENV`
// "development" a "vi.stubEnv" meghívása előtt

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 változtatja meg a többi környezeti változót
import.meta.env.MODE === 'development';

TIP

Az értéket egyszerűen hozzárendeléssel is megváltoztathatja, de ekkor nem fogja tudni használni a vi.unstubAllEnvs függvényt az előző érték visszaállítására:

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

vi.unstubAllEnvs ​

  • Típus: () => Vitest

Visszaállítja az összes import.meta.env és process.env értéket, amelyet a vi.stubEnv megváltoztatott. Amikor először hívják meg, a Vitest megjegyzi az eredeti értéket, és tárolja azt, amíg az unstubAllEnvs újra meg nem hívják.

ts
import { vi } from 'vitest';

// `process.env.NODE_ENV` és `import.meta.env.NODE_ENV`
// "development" a stubEnv meghívása előtt

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

// visszaállítja az első "stubEnv" hívás előtt tárolt értékre
process.env.NODE_ENV === 'development';
import.meta.env.NODE_ENV === 'development';

vi.stubGlobal ​

  • Típus: (name: string | number | symbol, value: unknown) => Vitest

Megváltoztatja egy globális változó értékét. Az eredeti értékét visszaállíthatja a vi.unstubAllGlobals meghívásával.

ts
import { vi } from 'vitest';

// az `innerWidth` "0" a stubGlobal meghívása előtt

vi.stubGlobal('innerWidth', 100);

innerWidth === 100;
globalThis.innerWidth === 100;
// ha jsdom-ot vagy happy-dom-ot használ
window.innerWidth === 100;

TIP

Az értéket egyszerűen hozzárendeléssel is megváltoztathatja a globalThis vagy window (ha jsdom vagy happy-dom környezetet használ) objektumhoz, de ekkor nem fogja tudni használni a vi.unstubAllGlobals függvényt az eredeti érték visszaállítására:

ts
globalThis.innerWidth = 100;
// ha jsdom-ot vagy happy-dom-ot használ
window.innerWidth = 100;

vi.unstubAllGlobals ​

  • Típus: () => Vitest

Visszaállítja az összes globális értéket a globalThis/global (és window/top/self/parent, ha jsdom vagy happy-dom környezetet használ) objektumon, amelyet a vi.stubGlobal megváltoztatott. Amikor először hívják meg, a Vitest megjegyzi az eredeti értéket, és tárolja azt, amíg az unstubAllGlobals újra meg nem hívják.

ts
import { vi } from 'vitest';

const Mock = vi.fn();

// az IntersectionObserver "undefined" a "stubGlobal" meghívása előtt

vi.stubGlobal('IntersectionObserver', Mock);

IntersectionObserver === Mock;
global.IntersectionObserver === Mock;
globalThis.IntersectionObserver === Mock;
// ha jsdom-ot vagy happy-dom-ot használ
window.IntersectionObserver === Mock;

vi.unstubAllGlobals();

globalThis.IntersectionObserver === undefined;
'IntersectionObserver' in globalThis === false;
// ReferenceError-t dob, mert nincs definiálva
IntersectionObserver === undefined;

Hamis időzítők ​

Ez a szakasz leírja, hogyan kell dolgozni a hamis időzítőkkel.

vi.advanceTimersByTime ​

  • Típus: (ms: number) => Vitest

Ez a metódus minden inicializált időzítőt végrehajt, amíg a megadott milliszekundum el nem telik, vagy a sor üres nem lesz – attól függően, hogy melyik következik előbb.

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

vi.advanceTimersByTime(150);

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

vi.advanceTimersByTimeAsync ​

  • Típus: (ms: number) => Promise<Vitest>

Ez a metódus minden inicializált időzítőt végrehajt, amíg a megadott milliszekundum el nem telik, vagy a sor üres nem lesz – attól függően, hogy melyik következik be előbb. Ez magában foglalja az aszinkron módon beállított időzítőket is.

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

await vi.advanceTimersByTimeAsync(150);

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

vi.advanceTimersToNextTimer ​

  • Típus: () => Vitest

Végrehajtja a következő elérhető időzítőt. Hasznos, ha minden időzítőhívás között ellenőrzéseket szeretne végezni. Láncoltan is hívhatja, hogy maga kezelje az időzítőket.

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

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

vi.advanceTimersToNextTimerAsync ​

  • Típus: () => Promise<Vitest>

Végrehajtja a következő elérhető időzítőt, és megvárja, amíg feloldódik, ha aszinkron módon lett beállítva. Hasznos, ha minden időzítőhívás között ellenőrzéseket szeretne végezni.

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+ ​

  • Típus: () => Vitest

Hasonló a vi.advanceTimersByTime függvényhez, de az időzítőket annyi milliszekundummal lépteti előre, amennyi a requestAnimationFrame segítségével jelenleg ütemezett visszahívások végrehajtásához szükséges.

ts
let frameRendered = false;

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

vi.advanceTimersToNextFrame();

expect(frameRendered).toBe(true);

vi.getTimerCount ​

  • Típus: () => number

Visszaadja a várakozó időzítők számát.

vi.clearAllTimers ​

Eltávolítja az összes futásra ütemezett időzítőt. Ezek az időzítők a jövőben soha nem fognak futni.

vi.getMockedSystemTime ​

  • Típus: () => Date | null

Visszaadja a mockolt aktuális dátumot. Ha a dátum nincs mockolva, a metódus null értéket ad vissza.

vi.getRealSystemTime ​

  • Típus: () => number

A vi.useFakeTimers használatakor a Date.now hívások mockoltak. Ha valós időt szeretne milliszekundumban lekérni, meghívhatja ezt a függvényt.

vi.runAllTicks ​

  • Típus: () => Vitest

Végrehajtja az összes mikrofeladatot, amelyet a process.nextTick sorba állított. Ez az összes önmaguk által ütemezett mikrofeladatot is futtatja.

vi.runAllTimers ​

  • Típus: () => Vitest

Ez a metódus minden inicializált időzítőt végrehajt, amíg az időzítősor üres nem lesz. Ez azt jelenti, hogy a runAllTimers során meghívott minden időzítő végrehajtódik. Ha végtelen intervalluma van, 10 000 próbálkozás után hibát jelez (konfigurálható a fakeTimers.loopLimit opcióval).

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 ​

  • Típus: () => Promise<Vitest>

Ez a metódus aszinkron módon végrehajtja az összes inicializált időzítőt, amíg az időzítősor ki nem ürül. Ez azt jelenti, hogy a runAllTimersAsync során meghívott minden időzítő végrehajtódik, még az aszinkron időzítők is. Ha végtelen intervalluma van, 10 000 próbálkozás után hibát jelez (konfigurálható a fakeTimers.loopLimit opcióval).

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

await vi.runAllTimersAsync();

// log: eredmény

vi.runOnlyPendingTimers ​

  • Típus: () => Vitest

Ez a metódus minden olyan időzítőt végrehajt, amelyet a vi.useFakeTimers hívás után inicializáltak. Nem fogja végrehajtani azokat az időzítőket, amelyeket a hívása során inicializáltak.

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

vi.runOnlyPendingTimers();

// log: 1

vi.runOnlyPendingTimersAsync ​

  • Típus: () => Promise<Vitest>

Ez a metódus aszinkron módon végrehajtja az összes olyan időzítőt, amelyet a vi.useFakeTimers hívás után inicializáltak, még az aszinkronokat is. Nem fogja végrehajtani azokat az időzítőket, amelyeket a hívása során inicializáltak.

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 ​

  • Típus: (date: string | number | Date) => void

Ha a hamis időzítők engedélyezve vannak, ez a metódus szimulálja, hogy a felhasználó megváltoztatja a rendszerórát (ez hatással lesz a dátummal kapcsolatos API-kra, mint például a hrtime, performance.now vagy new Date()) – azonban nem fog időzítőket végrehajtani. Ha a hamis időzítők nincsenek engedélyezve, ez a metódus csak a Date.* hívásokat mockolja.

Hasznos, ha bármit tesztelnie kell, ami az aktuális dátumtól függ – például a Luxon hívásokat a kódjában.

Ugyanazokat a string és szám argumentumokat fogadja el, mint a Date.

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

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

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

vi.useRealTimers();

vi.useFakeTimers ​

  • Típus: (config?: FakeTimerInstallOpts) => Vitest

Az időzítők mockolásának engedélyezéséhez meg kell hívnia ezt a metódust. Ez az összes további időzítőhívást (például setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, clearImmediate és Date) felülírja, amíg a vi.useRealTimers() meg nem hívódik.

A nextTick mockolása nem támogatott, ha a Vitestet node:child_process belsejében futtatja a --pool=forks használatával. A NodeJS belsőleg használja a process.nextTick függvényt a node:child_process környezetben, és lefagy, ha mockolva van. A nextTick mockolása támogatott, ha a Vitestet --pool=threads opcióval futtatja.

Az implementáció belsőleg a @sinonjs/fake-timers könyvtáron alapul.

TIP

A vi.useFakeTimers() nem mockolja automatikusan a process.nextTick és queueMicrotask függvényeket. De engedélyezheti ezt az opciót a toFake argumentumban: vi.useFakeTimers({ toFake: ['nextTick', 'queueMicrotask'] }).

vi.isFakeTimers ​

  • Típus: () => boolean

true értéket ad vissza, ha a hamis időzítők engedélyezettek.

vi.useRealTimers ​

  • Típus: () => Vitest

Amikor az időzítők lejárnak, meghívhatja ezt a metódust, hogy a mockolt időzítőket visszaállítsa eredeti implementációjukra. Az összes korábban ütemezett időzítő elvetésre kerül.

Egyéb ​

A Vitest által biztosított hasznos segédfüggvények.

vi.waitFor ​

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

Megvárja, amíg a visszahívás sikeresen végrehajtódik. Ha a visszahívás hibát dob, vagy elutasított promise-t ad vissza, tovább vár, amíg sikeres nem lesz, vagy időtúllépés nem következik be.

Ha az options számra van állítva, a hatás egyenértékű a { timeout: options } beállításával.

Ez nagyon hasznos, ha valamilyen aszinkron művelet befejezésére kell várnia, például amikor elindít egy szervert, és meg kell várnia, amíg elindul.

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

test('A szerver sikeresen elindult', async () => {
  const server = createServer();

  await vi.waitFor(
    () => {
      if (!server.isReady) {
        throw new Error('A szerver nem indult el');
      }

      console.log('A szerver elindult');
    },
    {
      timeout: 500, // alapértelmezett: 1000
      interval: 20, // alapértelmezett: 50
    }
  );
  expect(server.isReady).toBe(true);
});

Aszinkron visszahívások esetén is működik

ts
// @vitest-environment jsdom

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

test('Az elem létezik a DOM-ban', async () => {
  // DOM feltöltésének indítása
  populateDOMAsync();

  const element = await vi.waitFor(
    async () => {
      // próbálja meg lekérni az elemet, amíg létezik
      const element = (await getDOMElementAsync()) as HTMLElement | null;
      expect(element).toBeTruthy();
      expect(element.dataset.initialized).toBeTruthy();
      return element;
    },
    {
      timeout: 500, // alapértelmezett: 1000
      interval: 20, // alapértelmezett: 50
    }
  );
  expect(element).toBeInstanceOf(HTMLElement);
});

Ha a vi.useFakeTimers használatban van, a vi.waitFor automatikusan meghívja a vi.advanceTimersByTime(interval) függvényt minden ellenőrző visszahívásban.

vi.waitUntil ​

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

Ez hasonló a vi.waitFor függvényhez, de ha a visszahívás bármilyen hibát dob, a végrehajtás azonnal megszakad, és hibaüzenet jelenik meg. Ha a visszahívás hamis értéket ad vissza, a következő ellenőrzés folytatódik, amíg igaz érték nem tér vissza. Ez akkor hasznos, ha meg kell várnia, hogy valami létezzen, mielőtt megtenné a következő lépést.

Tekintse meg az alábbi példát. A vi.waitUntil segítségével megvárhatjuk, amíg az elem megjelenik az oldalon, majd elvégezhetünk valamilyen műveletet az elemmel.

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

test('Az elem helyesen renderelődik', async () => {
  const element = await vi.waitUntil(() => document.querySelector('.element'), {
    timeout: 500, // alapértelmezett: 1000
    interval: 20, // alapértelmezett: 50
  });

  // tegyen valamit az elemmel
  expect(element.querySelector('.element-child')).toBeTruthy();
});

vi.hoisted ​

  • Típus: <T>(factory: () => T) => T

Az ES modulokban az összes statikus import utasítás a fájl tetejére emelkedik, így minden olyan kód, amely az importok előtt van definiálva, valójában az importok kiértékelése után hajtódik végre.

Azonban hasznos lehet bizonyos mellékhatások kiváltása, például dátumok mockolása egy modul importálása előtt.

Ennek a korlátozásnak a megkerüléséhez átírhatja a statikus importokat dinamikus importokra az alábbiak szerint:

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

A vitest futtatásakor ezt automatikusan megteheti a vi.hoisted metódus használatával. A háttérben a Vitest a statikus importokat dinamikus importokká alakítja át, megőrizve az élő kötéseket.

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

AZ IMPORTOK NEM ELÉRHETŐK

A kód futtatása az importok előtt azt jelenti, hogy nem férhet hozzá az importált változókhoz, mert azok még nincsenek definiálva:

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

vi.hoisted(() => { value }); // hibát dob

Ez a kód hibát fog eredményezni:

Cannot access '__vi_0__' before initialization

Ha egy másik modulból származó változóhoz kell hozzáférnie a vi.hoisted belsejében, használjon dinamikus importot:

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

Azonban nem javasolt semmit importálni a vi.hoisted belsejében, mert az importok már emeltek – ha valamit a tesztek futtatása előtt kell végrehajtania, egyszerűen hajtsa végre magában az importált modulban.

Ez a metódus visszaadja a factory által visszaadott értéket. Ezt az értéket felhasználhatja a vi.mock factory-jaiban, ha könnyen hozzáférhetővé szeretné tenni a lokálisan definiált változókat:

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

Fontos megjegyezni, hogy ez a metódus aszinkron módon is meghívható, még akkor is, ha a környezete nem támogatja a legfelső szintű await-et:

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

vi.setConfig ​

  • Típus: RuntimeConfig

Frissíti a konfigurációt az aktuális tesztfájl számára. Ez a metódus csak azokat a konfigurációs opciókat támogatja, amelyek az aktuális tesztfájlt érintik:

ts
vi.setConfig({
  allowOnly: true,
  testTimeout: 10_000,
  hookTimeout: 10_000,
  clearMocks: true,
  restoreMocks: true,
  fakeTimers: {
    now: new Date(2021, 11, 19),
    // támogatja az egész objektumot
  },
  maxConcurrency: 10,
  sequence: {
    hooks: 'stack',
    // csak a "sequence.hooks" támogatott
  },
});

vi.resetConfig ​

  • Típus: RuntimeConfig

Ha a vi.setConfig korábban meghívásra került, ez visszaállítja a konfigurációt az eredeti állapotba.

Pager
Előző oldalMock Függvények
Következő oldalexpect

A MIT licenc alapján kiadva.

Copyright (c) 2021-Present Vitest Team

https://vitest.dev/api/vi

A MIT licenc alapján kiadva.

Copyright (c) 2021-Present Vitest Team