Vi
A Vitest a vi
segédfüggvényével kínál segédfüggvényeket. Globális változóként is elérheted (ha a globals konfiguráció engedélyezve van), vagy közvetlenül importálhatod a vitest
-ből:
import { vi } from 'vitest';
Mock modulok
Ez a szakasz azokat a programozói felületeket ismerteti, amelyeket a modulok mockolásakor használhatsz. Fontos tudni, hogy a Vitest nem támogatja a require()
használatával importált modulok mockolását.
vi.mock
- Típus:
(path: string, factory?: (importOriginal: () => unknown) => unknown) => void
A megadott path
elérési úton található összes importált modult egy másik modulra cseréli. Az elérési úton belül használhatod a konfigurált Vite aliasokat. A vi.mock
hívása feljebb van húzva, így nem számít, hogy hol hívod meg. Mindig az összes importálás előtt végrehajtásra kerül. Ha a hatókörön kívüli változókra kell hivatkoznod, azokat a vi.hoisted
segítségével definiálhatod, és a vi.mock
-ban hivatkozhatsz rájuk.
WARNING
A vi.mock
csak azokra a modulokra működik, amelyeket az import
kulcsszóval importáltak. A require
-rel nem működik.
A vi.mock
feljebb helyezéséhez a Vitest statikusan elemzi a fájljaidat. Ez azt jelenti, hogy a vi
, amelyet nem közvetlenül a vitest
csomagból importáltak (például egy segédfájlból), nem használható. Használd a vi.mock
-ot a vitest
-ből importált vi
-vel, vagy engedélyezd a globals
konfigurációs opciót.
A Vitest nem fogja mockolni azokat a modulokat, amelyeket egy setup fájlon belül importáltak, mert azok a tesztfájl futásakor már gyorsítótárazva vannak. Meghívhatod a vi.resetModules()
függvényt a vi.hoisted
belsejében, hogy töröld az összes modul gyorsítótárát a tesztfájl futtatása előtt.
WARNING
A böngésző üzemmód jelenleg nem támogatja a modulok mockolását. Ezt a fejlesztést a GitHub issue oldalon követheted nyomon.
Ha a factory
definiálva van, az összes importálás az eredményét adja vissza. A Vitest csak egyszer hívja meg a factory
-t, és az eredményeket az összes későbbi importáláshoz gyorsítótárazza a vi.unmock
vagy a vi.doUnmock
meghívásáig.
A jest
-tel ellentétben a factory
aszinkron is lehet. Használhatod a vi.importActual
függvényt vagy egy segédfüggvényt, amelynek a factory
-t adod át első argumentumként, és megkapod az eredeti modult belül.
import { vi } from 'vitest';
// ---cut---
// JavaScript használata esetén
vi.mock('./path/to/module.js', async importOriginal => {
const mod = await importOriginal();
return {
...mod,
// néhány export cseréje
namedExport: vi.fn(),
};
});
// TypeScript használata esetén
vi.mock('./path/to/module.js', async importOriginal => {
const mod = await importOriginal<typeof import('./path/to/module.js')>();
return {
...mod,
// néhány export cseréje
namedExport: vi.fn(),
};
});
WARNING
A vi.mock
fel van húzva (más szóval, a fájl tetejére van áthelyezve). Ez azt jelenti, hogy bárhol is írod (legyen az a beforeEach
vagy a test
belsejében), valójában azelőtt fog meghívásra kerülni.
Ez azt is jelenti, hogy nem használhatsz a factory-n belül olyan változókat, amelyek kívül vannak definiálva.
Ha változókat kell használnod a factory-n belül, próbáld ki a vi.doMock
függvényt. Ugyanúgy működik, de nincs feljebb helyezésre. Ne feledd, hogy csak a későbbi importálásokat mockolja.
Hivatkozhatsz a vi.hoisted
metódus által definiált változókra is, ha az a vi.mock
előtt lett deklarálva:
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 default exporttal mockolsz, akkor egy default
kulcsot kell megadnod a visszaadott factory függvény objektumon belül. Ez egy ES modul-specifikus figyelmeztetés; ezért a jest
dokumentációja eltérhet, mivel a jest
CommonJS modulokat használ. Például,
vi.mock('./path/to/module.js', () => {
return {
default: { myDefaultKey: vi.fn() },
namedExport: vi.fn(),
// stb...
};
});
Ha van egy __mocks__
mappa egy fájl mellett, amelyet mockolsz, és a factory nincs megadva, a Vitest megpróbál egy azonos nevű fájlt találni a __mocks__
almappában, és azt fogja eredeti modulként használni. Ha egy függőséget mockolsz, a Vitest megpróbál egy __mocks__
mappát találni a projekt gyökerében (alapértelmezés szerint process.cwd()
). A deps.moduleDirectories konfigurációs opcióval megadhatod a Vitest számára, hogy hol találhatók a függőségek.
Például, a következő fájlstruktúrád van:
- __mocks__
- axios.js
- src
__mocks__
- increment.js
- increment.js
- tests
- increment.test.js
Ha meghívod a vi.mock
függvényt egy tesztfájlban factory nélkül, akkor talál egy fájlt a __mocks__
mappában, amelyet modulként használhat:
// increment.test.js
import { vi } from 'vitest';
// az axios egy default export a `__mocks__/axios.js`-ből
import axios from 'axios';
// az increment egy named export a `src/__mocks__/increment.js`-ből
import { increment } from '../increment.js';
vi.mock('axios');
vi.mock('../increment.js');
axios.get(`/apples/${increment(1)}`);
WARNING
Ne feledd, hogy ha nem hívod meg a vi.mock
függvényt, a modulok nem lesznek automatikusan mockolva. A Jest automocking viselkedésének replikálásához meghívhatod a vi.mock
függvényt minden szükséges modulra a setupFiles
belsejében.
Ha nincs __mocks__
mappa vagy factory megadva, a Vitest importálja az eredeti modult, és automatikusan mockolja az összes exportját. Az alkalmazott szabályokért lásd az algoritmust.
vi.doMock
- Típus:
(path: string, factory?: (importOriginal: () => unknown) => unknown) => void
Ugyanaz, mint a vi.mock
, de nincs feljebb húzva a fájl tetejére, így hivatkozhatsz változókra a globális fájl hatókörében. A modul következő dinamikus importálása mockolva lesz.
WARNING
Ez nem fogja mockolni azokat a modulokat, amelyeket a függvény meghívása előtt importáltak. Ne feledd, hogy az ESM-ben az összes statikus importálás mindig feljebb kerül, így ha ezt a statikus importálás elé helyezed, az nem fogja kikényszeríteni, hogy az importálás előtt kerüljön meghívásra:
vi.doMock('./increment.js'); // ez az importálás _után_ fog meghívásra kerülni
import { increment } from './increment.js';
// ./increment.js
export function increment(number) {
return number + 1;
}
import { beforeEach, test } from 'vitest';
import { increment } from './increment.js';
// a modul nincs mockolva, mert a vi.doMock még nem lett meghívva
increment(1) === 2;
let mockedIncrement = 100;
beforeEach(() => {
// hozzáférhetsz a változókhoz egy factory-n belül
vi.doMock('./increment.js', () => ({ increment: () => ++mockedIncrement }));
});
test('a következő modul importálása a mockolt verziót importálja', async () => {
// az eredeti import NEM VOLT MOCKOLVA, mert a vi.doMock az importálások UTÁN kerül kiértékelésre
expect(increment(1)).toBe(2);
const { increment: mockedIncrement } = await import('./increment.js');
// az új dinamikus import a mockolt modult adja 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>
TypeScript típussegédfüggvény. Csak visszaadja az átadott objektumot.
Ha a partial
értéke true
, akkor egy Partial<T>
értéket vár vissza. Alapértelmezés szerint ez csak azt fogja elhitetni a TypeScripttel, hogy az első szintű értékek mockolva vannak. Átadhatsz egy { deep: true }
értéket második argumentumként, hogy közöld a TypeScripttel, hogy a teljes objektum mockolva van, ha az ténylegesen az.
import example from './example.js';
vi.mock('./example.js');
test('1 + 1 egyenlő 10', async () => {
vi.mocked(example.calc).mockReturnValue(10);
expect(example.calc(1, '+', 1)).toBe(10);
});
vi.importActual
- Típus:
<T>(path: string) => Promise<T>
Importálja a modult, megkerülve az összes ellenőrzést, hogy mockolni kell-e. Hasznos lehet, ha részlegesen szeretnél mockolni egy modult.
vi.mock('./example.js', async () => {
const axios = await vi.importActual('./example.js');
return { ...axios, get: vi.fn() };
});
vi.importMock
- Típus:
<T>(path: string) => Promise<MaybeMockedDeep<T>>
Importál egy modult 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ályokért lásd az algoritmust.
vi.unmock
- Típus:
(path: string) => void
Eltávolítja a modult a mockolt nyilvántartásból. Az importálásra irányuló összes hívás az eredeti modult adja vissza, még akkor is, ha korábban mockolva volt. Ez a hívás fel van húzva a fájl tetejére, így csak azokat a modulokat fogja unmockolni, amelyeket a setupFiles
-ban definiáltak.
vi.doUnmock
- Típus:
(path: string) => void
Ugyanaz, mint a vi.unmock
, de nem kerül feljebb helyezésre a fájl tetejére. A modul következő importálása az eredeti modult fogja importálni a mock helyett. Ez nem fogja unmockolni a korábban importált modulokat.
// ./increment.js
export function increment(number) {
return number + 1;
}
import { increment } from './increment.js';
// az increment már mockolva van, mert a vi.mock feljebb került
increment(1) === 100;
// ez feljebb kerül, és a factory az 1. sorban lévő importálás előtt kerül meghívásra
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 nem kerül feljebb, így a másik importálás unmockolt modult fog visszaadni
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álás unmockolt, most az `increment` az eredeti függvény, amely a count + 1 értéket 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 újbóli importáláskor. A legfelső szintű importálások nem értékelhetők újra. Hasznos lehet a modulok elkülönítésére, ahol a helyi állapot ütközik a tesztek között.
import { vi } from 'vitest';
import { data } from './data.js'; // Nem lesz újraértékelve a beforeEach tesztben
beforeEach(() => {
vi.resetModules();
});
test('állapot megváltoztatása', async () => {
const mod = await import('./some/path.js'); // Újraértékelésre kerül
mod.changeLocalState('new value');
expect(mod.getLocalState()).toBe('new value');
});
test('a modul régi állapottal rendelkezik', async () => {
const mod = await import('./some/path.js'); // Újraértékelésre kerül
expect(mod.getLocalState()).toBe('old value');
});
WARNING
Nem állítja vissza a mockok nyilvántartását. A mockok nyilvántartásának törléséhez használd a vi.unmock
vagy a vi.doUnmock
függvényt.
vi.dynamicImportSettled
Várja meg az összes importálás betöltését. Hasznos, ha van egy szinkron hívásod, amely elkezdi importálni egy modult, amelyre egyébként nem tudsz várni.
import { expect, test } from 'vitest';
// nem lehet nyomon követni az importálást, mert a Promise nem kerül visszaadásra
function renderComponent() {
import('./component.js').then(({ render }) => {
render();
});
}
test('a műveletek feloldásra kerülnek', async () => {
renderComponent();
await vi.dynamicImportSettled();
expect(document.querySelector('.component')).not.toBeNull();
});
TIP
Ha egy dinamikus importálás során egy másik dinamikus importálás indul el, ez a metódus megvárja, amíg mindegyik feloldásra kerül.
Ez a metódus az importálás feloldása után a következő setTimeout
tick-re is vár, így minden szinkron műveletnek be kell fejeződnie, mire feloldásra kerül.
Függvények és objektumok mockolása
Ez a szakasz a metódus mockokkal való munkát, valamint a környezeti és globális változók cseréjét ismerteti.
vi.fn
- Típus:
(fn?: Function) => Mock
Figyelőfüggvényt hoz létre egy függvényen, bár függvény nélkül is elindítható. Minden alkalommal, amikor egy függvény meghívásra kerül, tárolja a hívási argumentumait, a visszatérési értékeit és a példányait. Ezenkívül a metódusokkal manipulálhatod a viselkedését. Ha nincs megadva függvény, a mock undefined
értéket ad vissza, amikor meghívják.
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
- Típus:
(fn: Function) => boolean
Ellenőrzi, hogy egy adott paraméter mock függvény-e. Ha TypeScriptet használsz, akkor a típusát is szűkíti.
vi.clearAllMocks
Meghívja a .mockClear()
függvényt az összes figyelőn. Ez törli a mock előzményeit, de nem állítja vissza az implementációját az alapértelmezettre.
vi.resetAllMocks
Meghívja a .mockReset()
függvényt az összes figyelőn. Ez törli a mock előzményeit, és visszaállítja az implementációját egy üres függvényre (amely undefined
értéket ad vissza).
vi.restoreAllMocks
Meghívja a .mockRestore()
függvényt az összes figyelőn. Ez törli a mock előzményeit, és visszaállítja az implementációját az eredetire.
vi.spyOn
- Típus:
<T, K extends keyof T>(object: T, method: K, accessType?: 'get' | 'set') => MockInstance
Kémkedést hoz létre egy objektum metódusán vagy getter/setterén, hasonlóan a vi.fn()
függvényhez. Visszaad egy mock függvényt.
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
Meghívhatod a vi.restoreAllMocks
függvényt az afterEach
belsejében (vagy engedélyezheted a test.restoreMocks
beállítást), hogy visszaállítsd az összes metódust az eredeti implementációjára. Ez visszaállítja az eredeti objektum leírót, így nem fogod tudni megváltoztatni a metódus implementációját:
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!
vi.stubEnv 0.26.0+
- Típus:
(name: string, value: string) => Vitest
Megváltoztatja a környezeti változó értékét a process.env
-en és az import.meta.env
-en. Visszaállíthatod az értékét a vi.unstubAllEnvs
meghívásával.
import { vi } from 'vitest';
// a `process.env.NODE_ENV` és az `import.meta.env.NODE_ENV`
// "development" értékű a "vi.stubEnv" meghívása előtt
vi.stubEnv('NODE_ENV', 'production');
process.env.NODE_ENV === 'production';
import.meta.env.NODE_ENV === 'production';
// 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áltoztathatod, de nem fogod tudni használni a vi.unstubAllEnvs
függvényt az előző érték visszaállításához:
import.meta.env.MODE = 'test';
vi.unstubAllEnvs 0.26.0+
- Típus:
() => Vitest
Visszaállítja az összes import.meta.env
és process.env
változó értékét, amelyet a vi.stubEnv
megváltoztatott. Amikor először hívják meg, a Vitest elmenti az eredeti értéket, és tárolja azt, amíg a unstubAllEnvs
újra meg nem hívják.
import { vi } from 'vitest';
// a `process.env.NODE_ENV` és az `import.meta.env.NODE_ENV`
// "development" értékű 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. Visszaállíthatod az eredeti értékét a vi.unstubAllGlobals
meghívásával.
import { vi } from 'vitest';
// az `innerWidth` "0" értékű a stubGlobal meghívása előtt
vi.stubGlobal('innerWidth', 100);
innerWidth === 100;
globalThis.innerWidth === 100;
// ha jsdom-ot vagy happy-dom-ot használsz
window.innerWidth === 100;
TIP
Az értéket egyszerűen hozzárendeléssel is megváltoztathatod a globalThis
-hez vagy a window
-hoz (ha jsdom
vagy happy-dom
környezetet használsz), de nem fogod tudni használni a vi.unstubAllGlobals
függvényt az eredeti érték visszaállításához:
globalThis.innerWidth = 100;
// ha jsdom-ot vagy happy-dom-ot használsz
window.innerWidth = 100;
vi.unstubAllGlobals 0.26.0+
- Típus:
() => Vitest
Visszaállítja az összes globális változó értékét a globalThis
/global
-on (és a window
/top
/self
/parent
-en, ha jsdom
vagy happy-dom
környezetet használsz), amelyet a vi.stubGlobal
megváltoztatott. Amikor először hívják meg, a Vitest elmenti az eredeti értéket, és tárolja azt, amíg a unstubAllGlobals
újra meg nem hívják.
import { vi } from 'vitest';
const Mock = vi.fn();
// az IntersectionObserver "undefined" értékű 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álsz
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 rész leírja, hogyan kell dolgozni a hamis időzítőkkel.
vi.advanceTimersByTime
- Típus:
(ms: number) => Vitest
Ez a metódus lépteti az időzítőket a megadott milliszekundumok számával. Meghív minden elindított időzítőt, amíg a megadott idő el nem telik, vagy az időzítők sora ki nem ürül, attól függően, melyik következik be előbb.
import { vi } from 'vitest';
// ---cut---
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 aszinkron módon lépteti az időzítőket a megadott milliszekundumok számával. Meghív minden elindított időzítőt, amíg a megadott idő el nem telik, vagy az időzítők sora ki nem ürül, attól függően, melyik következik be előbb. Ez magában foglalja az aszinkron módon beállított időzítőket is.
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
- Típus:
() => Vitest
Meghívja a következő esedékes időzítőt. Hasznos állítások készítéséhez az egyes időzítőhívások között. Az időzítőket láncolt hívásokkal kezelheti.
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
- Típus:
() => Promise<Vitest>
Meghívja a következő esedékes időzítőt, és megvárja, amíg feloldódik, ha aszinkron módon lett beállítva. Hasznos állítások készítéséhez az egyes időzítőhívások között.
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
- Típus:
() => number
Lekéri a várakozó (még le nem járt) 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 nem fognak lefutni.
vi.getMockedSystemTime
- Típus:
() => Date | null
Visszaadja a setSystemTime
használatával beállított hamisított aktuális dátumot. Ha a dátum nincs hamisítva, a metódus null
értéket ad vissza.
vi.getRealSystemTime
- Típus:
() => number
A vi.useFakeTimers
használatakor a Date.now
hívások hamisítva vannak. Ha valós időpontra van szüksége milliszekundumban, meghívhatja ezt a függvényt.
vi.runAllTicks
- Típus:
() => Vitest
Meghív minden mikrofeladatot, amelyet a process.nextTick
sorba állított. Ez a saját maguk által ütemezett összes mikrofeladatot is futtatja.
vi.runAllTimers
- Típus:
() => Vitest
Ez a metódus meghív minden elindított időzítőt, amíg az időzítő sor üres nem lesz. Ez azt jelenti, hogy a runAllTimers
hívás során elindított összes időzítő lefut. Ha végtelen intervalluma van, az 10 000 próbálkozás után hibát fog dobni (konfigurálható a fakeTimers.loopLimit
segítségével).
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
- Típus:
() => Promise<Vitest>
Ez a metódus aszinkron módon meghív minden elindított időzítőt, amíg az időzítő sor üres nem lesz. Ez azt jelenti, hogy a runAllTimersAsync
hívás során elindított összes időzítő lefut, beleértve az aszinkron időzítőket is. Ha végtelen intervalluma van, az 10 000 próbálkozás után hibát fog dobni (konfigurálható a fakeTimers.loopLimit
segítségével).
import { vi } from 'vitest';
// ---cut---
setTimeout(async () => {
console.log(await Promise.resolve('result'));
}, 100);
await vi.runAllTimersAsync();
// log: result
vi.runOnlyPendingTimers
- Típus:
() => Vitest
Ez a metódus meghív minden időzítőt, amelyet a vi.useFakeTimers
hívás után indítottak el. Nem futtat egyetlen időzítőt sem, amelyet a hívása során indítottak el.
import { vi } from 'vitest';
// ---cut---
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 meghív minden időzítőt, amelyet a vi.useFakeTimers
hívás után indítottak el, beleértve az aszinkron időzítőket is. Nem futtat egyetlen időzítőt sem, amelyet a hívása során indítottak el.
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
- Típus:
(date: string | number | Date) => void
Ha a hamis időzítők engedélyezve vannak, ez a metódus szimulálja a rendszeróra felhasználó általi megváltoztatását (ami hatással van a dátummal kapcsolatos API-kra, mint például a hrtime
, a performance.now
vagy a new Date()
), de nem futtat időzítőket. Ha a hamis időzítők nincsenek engedélyezve, ez a metódus csak a Date.*
hívásokat fogja hamisítani.
Hasznos, ha tesztelni kell valamit, ami az aktuális dátumtól függ - például a Luxon hívásokat a kódban.
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
- Típus:
(config?: FakeTimerInstallOpts) => Vitest
Az időzítők hamisításához meg kell hívnia ezt a metódust. Ez átveszi az összes további időzítőhívást (például setTimeout
, setInterval
, clearTimeout
, clearInterval
, setImmediate
, clearImmediate
és Date
), amíg a vi.useRealTimers()
meg nem hívódik.
A nextTick
hamisítása nem támogatott, ha a Vitest a node:child_process
modulban fut --pool=forks
használatával. A NodeJS belsőleg használja a process.nextTick
függvényt a node:child_process
modulban, és lefagy, ha az hamisítva van. A nextTick
hamisítása támogatott, ha a Vitest a --pool=threads
kapcsolóval fut.
A megvalósítás belsőleg a @sinonjs/fake-timers
-en alapul.
TIP
A 0.35.0
verziótól kezdve a vi.useFakeTimers()
már nem hamisítja automatikusan a process.nextTick
-et. Ez továbbra is hamisítható, ha megadja az opciót a toFake
argumentumban: vi.useFakeTimers({ toFake: ['nextTick'] })
.
vi.isFakeTimers 0.34.5+
- Típus:
() => boolean
true
értéket ad vissza, ha a hamis időzítők engedélyezve vannak.
vi.useRealTimers
- Típus:
() => Vitest
Amikor az időzítők lejárnak, meghívhatja ezt a metódust, hogy visszaállítsa a hamisított időzítőket az eredeti implementációikra. Az összes korábban ütemezett időzítő el lesz dobva.
Vegyes
A Vitest által biztosított hasznos segédfüggvények halmaza.
vi.waitFor 0.34.5+
- Típus:
<T>(callback: WaitForCallback<T>, options?: number | WaitForOptions) => Promise<T>
Várja meg, amíg a visszahívás sikeresen lefut. Ha a visszahívás hibát dob, vagy elutasított promise-t ad vissza, akkor addig vár, amíg sikeres nem lesz, vagy időtúllépés nem következik be.
Ez nagyon hasznos, ha meg kell várnia, amíg egy aszinkron művelet befejeződik, például amikor elindít egy szervert, és meg kell várnia, amíg elindul.
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, // alapértelmezett: 1000
interval: 20, // alapértelmezett: 50
}
);
expect(server.isReady).toBe(true);
});
Aszinkron visszahívásokhoz is működik
// @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, // 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)
-t minden ellenőrző visszahívásban.
vi.waitUntil 0.34.5+
- Típus:
<T>(callback: WaitUntilCallback<T>, options?: number | WaitUntilOptions) => Promise<T>
Ez hasonló a vi.waitFor
-hoz, de ha a visszahívás hibát dob, a végrehajtás azonnal megszakad, és hibaüzenet érkezik. Ha a visszahívás hamis értéket ad vissza, a következő ellenőrzés addig folytatódik, amíg igaz értéket nem ad vissza. Ez akkor hasznos, ha meg kell várnia, amíg valami létezik, mielőtt a következő lépést megtenné.
Nézze meg az alábbi példát. A vi.waitUntil
segítségével megvárhatjuk, amíg az elem megjelenik az oldalon, majd tehetünk valamit az elemmel.
import { expect, test, vi } from 'vitest';
test('Element render correctly', async () => {
const element = await vi.waitUntil(() => document.querySelector('.element'), {
timeout: 500, // alapértelmezett: 1000
interval: 20, // alapértelmezett: 50
});
// do something with the element
expect(element.querySelector('.element-child')).toBeTruthy();
});
vi.hoisted 0.31.0+
- Típus:
<T>(factory: () => T) => T
Az ES modulokban lévő összes statikus import
utasítás a fájl tetejére kerül (hoisted), ezért az importok előtt definiált kód valójában az importok kiértékelése után fut le.
Azonban hasznos lehet néhány mellékhatás meghívása, például a dátumok hamisítása egy modul importálása előtt.
A korlátozás megkerüléséhez átírhatja a statikus importokat dinamikus importokká, például így:
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.
- callFunctionWithSideEffect()
import { value } from './some/module.js'
+ vi.hoisted(() => callFunctionWithSideEffect())
Ez a metódus visszaadja a gyár által visszaadott értéket. Ezt az értéket felhasználhatja a vi.mock
gyáraiban, ha könnyen hozzá szeretne férni a helyben definiált változókhoz:
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);
Vegye figyelembe, 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:
const promised = await vi.hoisted(async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
return response.json();
});
vi.setConfig
- Típus:
RuntimeConfig
Frissíti az aktuális tesztfájl konfigurációját. Ez a metódus csak azokat a konfigurációs opciókat támogatja, amelyek hatással vannak az aktuális tesztfájlra.
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
- Típus:
RuntimeConfig
Ha a vi.setConfig
korábban meg lett hívva, ez visszaállítja a konfigurációt az eredeti állapotba.