Vi
Vitest fornisce funzioni di utilità tramite l'helper vi
. Puoi accedervi globalmente (quando la configurazione globals è abilitata), oppure importarlo da vitest
:
import { vi } from 'vitest';
vi.advanceTimersByTime
Tipo:
(ms: number) => Vitest
Si comporta esattamente come
runAllTimers
, ma si arresta dopo il numero di millisecondi specificato. Ad esempio, questo stamperà1, 2, 3
senza generare errori:tslet i = 0; setInterval(() => console.log(++i), 50); vi.advanceTimersByTime(150);
vi.advanceTimersByTimeAsync
Tipo:
(ms: number) => Promise<Vitest>
Si comporta esattamente come
runAllTimersAsync
, ma si arresta dopo il numero di millisecondi specificato. Questo includerà i timer impostati in modo asincrono. Ad esempio, questo stamperà1, 2, 3
senza generare errori:tslet i = 0; setInterval(() => Promise.resolve().then(() => console.log(++i)), 50); await vi.advanceTimersByTimeAsync(150);
vi.advanceTimersToNextTimer
Tipo:
() => Vitest
Esegue il prossimo timer disponibile. Utile per effettuare asserzioni tra una chiamata e l'altra al timer. Puoi concatenare le chiamate per gestire i timer in modo indipendente.
tslet i = 0; setInterval(() => console.log(++i), 50); vi.advanceTimersToNextTimer() // stampa 1 .advanceTimersToNextTimer() // stampa 2 .advanceTimersToNextTimer(); // stampa 3
vi.advanceTimersToNextTimerAsync
Tipo:
() => Promise<Vitest>
Esegue il prossimo timer disponibile, anche se è stato impostato in modo asincrono. Utile per effettuare asserzioni tra una chiamata e l'altra al timer. Puoi concatenare le chiamate per gestire i timer in modo indipendente.
tslet i = 0; setInterval(() => Promise.resolve().then(() => console.log(++i)), 50); vi.advanceTimersToNextTimerAsync() // stampa 1 .advanceTimersToNextTimerAsync() // stampa 2 .advanceTimersToNextTimerAsync(); // stampa 3
vi.getTimerCount
Tipo:
() => number
Restituisce il numero di timer in attesa di esecuzione.
vi.clearAllMocks
Chiama .mockClear()
su tutte le spie (spies). Questo cancellerà la cronologia dei mock, ma non reimposterà l'implementazione a quella predefinita.
vi.clearAllTimers
Rimuove tutti i timer programmati per l'esecuzione. Questi timer non verranno mai eseguiti.
vi.dynamicImportSettled
Attende che tutti gli import dinamici siano stati caricati. Utile se hai una chiamata sincrona che avvia l'importazione di un modulo, che altrimenti non potresti attendere.
vi.fn
Tipo:
(fn?: Function) => Mock
Crea una spia (spy) su una funzione, anche se può essere avviata senza una funzione esistente. Ogni volta che la funzione viene chiamata, registra i suoi argomenti, i valori di ritorno e le istanze. Inoltre, puoi manipolare il suo comportamento con i metodi. Se non viene fornita una funzione, la simulazione restituirà
undefined
quando viene invocata.tsconst 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.getMockedSystemTime
Tipo:
() => Date | null
Restituisce la data corrente simulata impostata usando
setSystemTime
. Se la data non è simulata, restituirànull
.
vi.getRealSystemTime
Tipo:
() => number
Quando utilizzi
vi.useFakeTimers
, le chiamate aDate.now
vengono simulate. Se hai bisogno di ottenere il tempo reale in millisecondi, puoi chiamare questa funzione.
vi.hoisted
Tipo:
<T>(factory: () => T) => T
Versione: Da Vitest 0.31.0
Tutte le istruzioni
import
statiche nei moduli ES vengono spostate all'inizio del file. Di conseguenza, qualsiasi codice definito prima degli import verrà effettivamente eseguito dopo che gli import sono stati valutati.Tuttavia, può essere utile invocare effetti collaterali, come la simulazione delle date, prima di importare un modulo.
Per ovviare a questa limitazione, puoi convertire gli import statici in dinamici, come mostrato di seguito:
diffcallFunctionWithSideEffect() - import { value } from './some/module.ts' + const { value } = await import('./some/module.ts')
Quando esegui
vitest
, puoi farlo automaticamente utilizzando il metodovi.hoisted
.diff- callFunctionWithSideEffect() import { value } from './some/module.ts' + vi.hoisted(() => callFunctionWithSideEffect())
Questo metodo restituisce il valore fornito dalla factory. Puoi utilizzare quel valore nelle tue factory
vi.mock
se hai bisogno di un facile accesso alle variabili definite localmente:tsimport { 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);
vi.mock
Tipo:
(path: string, factory?: () => unknown) => void
Sostituisce tutti i moduli importati dal
path
fornito con un modulo alternativo. Puoi utilizzare gli alias di Vite configurati all'interno di un percorso. La chiamata avi.mock
viene spostata all'inizio del file, quindi non importa dove la chiami: verrà sempre eseguita prima di tutti gli import. Se hai bisogno di fare riferimento ad alcune variabili al di fuori del suo scope, puoi definirle all'interno divi.hoisted
e farvi riferimento all'interno divi.mock
.WARNING
vi.mock
funziona solo per i moduli che sono stati importati con la parola chiaveimport
. Non funziona conrequire
.Vitest analizza staticamente i tuoi file per sollevare
vi.mock
. Ciò significa che non puoi utilizzarevi
se non è stato importato direttamente dal pacchettovitest
(ad esempio, da un file di utilità locale). Per risolvere questo problema, usa semprevi.mock
convi
importato davitest
, oppure abilita l'opzione di configurazioneglobals
.WARNING
La simulazione dei moduli non è attualmente supportata nella modalità browser. Puoi seguire lo stato di questa funzionalità nella issue su GitHub.
Se
factory
è definita, tutti gli import restituiranno il suo risultato. Vitest chiama la factory solo una volta e memorizza nella cache il risultato per tutti gli import successivi, fino a quando non viene chiamatovi.unmock
ovi.doUnmock
.A differenza di
jest
, la funzione factory può essere asincrona, quindi puoi usarevi.importActual
o un helper, ricevuto come primo argomento, al suo interno per ottenere il modulo originale.tsvi.mock('./path/to/module.js', async importOriginal => { const mod = await importOriginal(); return { ...mod, // sostituire alcune esportazioni namedExport: vi.fn(), }; });
WARNING
vi.mock
viene sollevato (in altre parole, spostato) all'inizio del file. Ciò significa che, ovunque lo scrivi (che sia all'interno dibeforeEach
otest
), verrà effettivamente chiamato prima di qualsiasi altra istruzione.Questo significa anche che non puoi utilizzare variabili all'interno della factory che siano definite al di fuori del suo scope.
Se hai bisogno di utilizzare variabili all'interno della factory, prova
vi.doMock
. Funziona allo stesso modo, ma non è sollevato. Fai attenzione che simula solo gli import successivi.Puoi anche fare riferimento a variabili definite dal metodo
vi.hoisted
se è stato dichiarato prima divi.mock
:tsimport { 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
Se stai simulando un modulo con esportazione predefinita, dovrai fornire una chiave
default
all'interno dell'oggetto restituito dalla funzione factory. Questa è una avvertenza specifica per i moduli ES, quindi la documentazione dijest
potrebbe differire poichéjest
utilizza i moduli CommonJS. Per esempio:tsvi.mock('./path/to/module.js', () => { return { default: { myDefaultKey: vi.fn() }, namedExport: vi.fn(), // ecc... }; });
Se esiste una cartella
__mocks__
accanto a un file che stai simulando, e la factory non è fornita, Vitest cercherà un file con lo stesso nome nella sottocartella__mocks__
e lo userà come modulo effettivo. Se stai simulando una dipendenza, Vitest cercherà di trovare una cartella__mocks__
nella root del progetto (il valore predefinito èprocess.cwd()
). Puoi indicare a Vitest dove si trovano le dipendenze tramite l'opzione di configurazione deps.moduleDirectories.Ad esempio, hai questa struttura di file:
- __mocks__ - axios.js - src __mocks__ - increment.js - increment.js - tests - increment.test.js
Se chiami
vi.mock
in un file di test senza fornire una factory, troverà un file nella cartella__mocks__
da usare come modulo:ts// increment.test.js import { vi } from 'vitest'; // axios è una esportazione predefinita da `__mocks__/axios.js` import axios from 'axios'; // increment è una esportazione nominata da `src/__mocks__/increment.js` import { increment } from '../increment.js'; vi.mock('axios'); vi.mock('../increment.js'); axios.get(`/apples/${increment(1)}`);
WARNING
Nota che se non chiami
vi.mock
, i moduli non vengono simulati automaticamente. Per replicare il comportamento di automocking di Jest, puoi chiamarevi.mock
per ogni modulo richiesto all'interno disetupFiles
.Se non esiste una cartella
__mocks__
o una factory fornita, Vitest importerà il modulo originale e simulerà automaticamente tutte le sue esportazioni. Per le regole applicate, consulta l'algoritmo.
vi.doMock
Tipo:
(path: string, factory?: () => unknown) => void
È identico a
vi.mock
, ma non viene sollevato all'inizio del file. Di conseguenza, puoi fare riferimento a variabili nello scope globale del file. Il prossimo import dinamico del modulo verrà simulato. Questo non simulerà i moduli che sono stati importati prima che questo venisse chiamato.
// ./increment.js
export function increment(number) {
return number + 1;
}
import { beforeEach, test } from 'vitest';
import { increment } from './increment.js';
// il modulo non è simulato, perché vi.doMock non è ancora stato chiamato
increment(1) === 2;
let mockedIncrement = 100;
beforeEach(() => {
// puoi accedere alle variabili all'interno di una factory
vi.doMock('./increment.js', () => ({ increment: () => ++mockedIncrement }));
});
test('importing the next module imports mocked one', async () => {
// l'import originale NON È STATO SIMULATO, perché `vi.doMock` viene valutato DOPO l'esecuzione degli import statici
expect(increment(1)).toBe(2);
const { increment: mockedIncrement } = await import('./increment.js');
// il nuovo import dinamico fornirà il modulo simulato
expect(mockedIncrement(1)).toBe(101);
expect(mockedIncrement(1)).toBe(102);
expect(mockedIncrement(1)).toBe(103);
});
vi.mocked
Tipo:
<T>(obj: T, deep?: boolean) => MaybeMockedDeep<T>
Tipo:
<T>(obj: T, options?: { partial?: boolean; deep?: boolean }) => MaybePartiallyMockedDeep<T>
Utilità di tipo per TypeScript. In realtà restituisce solo l'oggetto che è stato passato.
Quando
partial
ètrue
, si aspetterà unPartial<T>
come valore di ritorno.tsimport example from './example.js'; vi.mock('./example.js'); test('1+1 equals 2', async () => { vi.mocked(example.calc).mockRestore(); const res = example.calc(1, '+', 1); expect(res).toBe(2); });
vi.importActual
Tipo:
<T>(path: string) => Promise<T>
Importa il modulo, bypassando tutti i controlli relativi alla simulazione. Può essere utile se si desidera simulare il modulo parzialmente.
tsvi.mock('./example.js', async () => { const axios = await vi.importActual('./example.js'); return { ...axios, get: vi.fn() }; });
vi.importMock
Tipo:
<T>(path: string) => Promise<MaybeMockedDeep<T>>
Importa un modulo con tutte le sue proprietà (incluse le proprietà nidificate) simulate. Segue le stesse regole di
vi.mock
. Per le regole applicate, consulta l'algoritmo.
vi.resetAllMocks
Chiama .mockReset()
su tutte le spie (spies). Questo cancellerà la cronologia dei mock e reimposterà l'implementazione a una funzione vuota (che restituirà undefined
).
vi.resetConfig
Tipo:
RuntimeConfig
Se
vi.setConfig
è stato chiamato in precedenza, questo reimposterà la configurazione allo stato originale.
vi.resetModules
Tipo:
() => Vitest
Reimposta il registro dei moduli cancellando la cache di tutti i moduli. Ciò consente ai moduli di essere rivalutati quando vengono reimportati. Gli import di livello superiore non possono essere rivalutati. Potrebbe essere utile per isolare i moduli in cui lo stato locale è in conflitto tra i test.
tsimport { vi } from 'vitest'; import { data } from './data.js'; // Non verrà rivalutato prima di ogni test beforeEach(() => { vi.resetModules(); }); test('change state', async () => { const mod = await import('./some/path.js'); // Verrà rivalutato mod.changeLocalState('new value'); expect(mod.getLocalState()).toBe('new value'); }); test('module has old state', async () => { const mod = await import('./some/path.js'); // Verrà rivalutato expect(mod.getLocalState()).toBe('old value'); });
WARNING
Non reimposta il registro dei mock. Per cancellare il registro dei mock, usa vi.unmock
o vi.doUnmock
.
vi.restoreAllMocks
Chiama .mockRestore()
su tutte le spie (spies). Questo cancellerà la cronologia dei mock e reimposterà l'implementazione a quella originale.
vi.stubEnv
Tipo:
(name: string, value: string) => Vitest
Versione: Da Vitest 0.26.0
Imposta il valore della variabile d'ambiente su
process.env
eimport.meta.env
. Puoi ripristinare il suo valore chiamandovi.unstubAllEnvs
.
import { vi } from 'vitest';
// `process.env.NODE_ENV` e `import.meta.env.NODE_ENV`
// sono "development" prima di chiamare "vi.stubEnv"
vi.stubEnv('NODE_ENV', 'production');
process.env.NODE_ENV === 'production';
import.meta.env.NODE_ENV === 'production';
// non cambia altri env
import.meta.env.MODE === 'development';
TIP
Puoi anche cambiare il valore semplicemente assegnandolo, ma non sarai in grado di usare vi.unstubAllEnvs
per ripristinare il valore precedente:
import.meta.env.MODE = 'test';
vi.unstubAllEnvs
Tipo:
() => Vitest
Versione: Da Vitest 0.26.0
Ripristina tutti i valori di
import.meta.env
eprocess.env
che sono stati modificati davi.stubEnv
. Alla prima chiamata, Vitest memorizza il valore originale e lo conserva fino a quandounstubAllEnvs
non viene richiamato.
import { vi } from 'vitest';
// `process.env.NODE_ENV` e `import.meta.env.NODE_ENV`
// sono "development" prima di chiamare 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();
// ripristina il valore memorizzato prima della prima chiamata a "stubEnv"
process.env.NODE_ENV === 'development';
import.meta.env.NODE_ENV === 'development';
vi.stubGlobal
Tipo:
(name: string | number | symbol, value: unknown) => Vitest
Modifica il valore di una variabile globale. È possibile ripristinare il valore originale chiamando
vi.unstubAllGlobals
.
import { vi } from 'vitest';
// `innerWidth` è "0" prima di chiamare stubGlobal
vi.stubGlobal('innerWidth', 100);
innerWidth === 100;
globalThis.innerWidth === 100;
// se si utilizza jsdom o happy-dom
window.innerWidth === 100;
TIP
È possibile modificare il valore anche assegnandolo direttamente a globalThis
o window
(se si utilizza l'ambiente jsdom
o happy-dom
), ma in questo caso non sarà possibile utilizzare vi.unstubAllGlobals
per ripristinare il valore originale:
globalThis.innerWidth = 100;
// se si utilizza jsdom o happy-dom
window.innerWidth = 100;
vi.unstubAllGlobals
Tipo:
() => Vitest
Versione: Da Vitest 0.26.0
Ripristina tutti i valori globali su
globalThis
/global
(ewindow
/top
/self
/parent
, se si utilizza l'ambientejsdom
ohappy-dom
) che sono stati modificati convi.stubGlobal
. Alla prima chiamata, Vitest memorizza il valore originale e lo conserva fino a quandounstubAllGlobals
non viene richiamato.
import { vi } from 'vitest';
const Mock = vi.fn();
// IntersectionObserver è "undefined" prima di chiamare "stubGlobal"
vi.stubGlobal('IntersectionObserver', Mock);
IntersectionObserver === Mock;
global.IntersectionObserver === Mock;
globalThis.IntersectionObserver === Mock;
// se si utilizza jsdom o happy-dom
window.IntersectionObserver === Mock;
vi.unstubAllGlobals();
globalThis.IntersectionObserver === undefined;
'IntersectionObserver' in globalThis === false;
// genera un ReferenceError, perché non è definito
IntersectionObserver === undefined;
vi.runAllTicks
Tipo:
() => Vitest
Esegue ogni microtask che è stato accodato da
process.nextTick
. Questo eseguirà anche tutti i microtask pianificati da questi ultimi.
vi.runAllTimers
Tipo:
() => Vitest
Questo metodo invocherà tutti i timer impostati fino a quando la coda dei timer non sarà vuota. Ciò significa che ogni timer richiamato durante
runAllTimers
verrà eseguito. Se si ha un intervallo infinito, verrà generato un errore dopo 10.000 tentativi. Ad esempio, questo stamperà1, 2, 3
:tslet i = 0; setTimeout(() => console.log(++i)); const interval = setInterval(() => { console.log(++i); if (i === 3) clearInterval(interval); }, 50); vi.runAllTimers();
vi.runAllTimersAsync
Tipo:
() => Promise<Vitest>
Questo metodo invocherà in modo asincrono tutti i timer impostati fino a quando la coda dei timer non sarà vuota. Ciò significa che ogni timer richiamato durante
runAllTimersAsync
verrà eseguito, inclusi i timer asincroni. Se si ha un intervallo infinito, verrà generato un errore dopo 10.000 tentativi. Ad esempio, questo stamperàresult
:tssetTimeout(async () => { console.log(await Promise.resolve('result')); }, 100); await vi.runAllTimersAsync();
vi.runOnlyPendingTimers
Tipo:
() => Vitest
Questo metodo eseguirà tutti i timer che sono stati avviati dopo la chiamata a
vi.useFakeTimers()
. Non attiverà alcun timer che è stato avviato durante la sua esecuzione. Ad esempio, questo stamperà solo1
:tslet i = 0; setInterval(() => console.log(++i), 50); vi.runOnlyPendingTimers();
vi.runOnlyPendingTimersAsync
Tipo:
() => Promise<Vitest>
Questo metodo eseguirà in modo asincrono tutti i timer che sono stati avviati dopo la chiamata a
vi.useFakeTimers()
, inclusi quelli asincroni. Non attiverà alcun timer che è stato avviato durante la sua esecuzione. Ad esempio, questo stamperà2, 3, 3, 1
:tssetTimeout(() => { console.log(1); }, 100); setTimeout(() => { Promise.resolve().then(() => { console.log(2); setInterval(() => { console.log(3); }, 40); }); }, 10); await vi.runOnlyPendingTimersAsync();
vi.setSystemTime
Tipo:
(date: string | number | Date) => void
Imposta la data corrente a quella fornita. Tutte le chiamate a
Date
restituiranno questa data.Utile se è necessario testare qualsiasi cosa che dipenda dalla data corrente, ad esempio le chiamate luxon all'interno del codice.
tsconst date = new Date(1998, 11, 19); vi.useFakeTimers(); vi.setSystemTime(date); expect(Date.now()).toBe(date.valueOf()); vi.useRealTimers();
vi.setConfig
Tipo:
RuntimeConfig
Aggiorna la configurazione per il file di test corrente. È possibile influenzare solo i valori che vengono utilizzati durante l'esecuzione dei test.
vi.spyOn
Tipo:
<T, K extends keyof T>(object: T, method: K, accessType?: 'get' | 'set') => MockInstance
Crea una spia su un metodo o getter/setter di un oggetto.
tslet apples = 0; const cart = { getApples: () => 13, }; const spy = vi.spyOn(cart, 'getApples').mockImplementation(() => apples); apples = 1; expect(cart.getApples()).toBe(1); expect(spy).toHaveBeenCalled(); expect(spy).toHaveReturnedWith(1);
vi.stubGlobal
Tipo:
(key: keyof globalThis & Window, value: any) => Vitest
Inserisce un valore nella variabile globale. Se si utilizza
jsdom
ohappy-dom
, inserisce anche il valore nell'oggettowindow
.Per saperne di più, consultare la sezione "Mocking Globals" (Simulazione delle variabili globali).
vi.unmock
Tipo:
(path: string) => void
Rimuove il modulo dal registro dei mock. Tutte le chiamate a
import
restituiranno il modulo originale anche se è stato simulato in precedenza. Questa chiamata viene hoisted (sollevata) all'inizio del file, quindi ripristinerà solo i moduli che sono stati definiti insetupFiles
, ad esempio.
vi.doUnmock
Tipo:
(path: string) => void
Lo stesso di
vi.unmock
, ma non è hoisted (sollevata) all'inizio del file. La prossima importazione del modulo importerà il modulo originale invece del mock. Questo non smaschererà i moduli importati in precedenza.
// ./increment.js
export function increment(number) {
return number + 1;
}
import { increment } from './increment.js';
// increment è già simulato (mocked), perché vi.mock è sollevato
increment(1) === 100;
// questo è sollevato e la factory viene chiamata prima dell'importazione alla riga 1
vi.mock('./increment.js', () => ({ increment: () => 100 }));
// tutte le chiamate sono simulate (mocked) e `increment` restituisce sempre 100
increment(1) === 100;
increment(30) === 100;
// questo non è sollevato, quindi un'altra importazione restituirà il modulo non simulato (unmocked)
vi.doUnmock('./increment.js');
// questo RESTITUISCE ANCORA 100, perché `vi.doUnmock` non rivaluta un modulo
increment(1) === 100;
increment(30) === 100;
// la prossima importazione non è simulata (unmocked), ora `increment` è la funzione originale che restituisce count + 1
const { increment: unmockedIncrement } = await import('./increment.js');
unmockedIncrement(1) === 2;
unmockedIncrement(30) === 31;
vi.useFakeTimers
Tipo:
() => Vitest
Per abilitare il mocking dei timer, è necessario chiamare questo metodo. Intercetterà tutte le chiamate successive ai timer (come
setTimeout
,setInterval
,clearTimeout
,clearInterval
,nextTick
,setImmediate
,clearImmediate
eDate
), fino a quando non viene chiamatovi.useRealTimers()
.Il mocking di
nextTick
non è supportato quando si esegue Vitest all'interno dinode:child_process
utilizzando--no-threads
. NodeJS utilizzaprocess.nextTick
internamente innode:child_process
e si blocca quando viene simulato. Il mocking dinextTick
è supportato quando si esegue Vitest con--threads
.L'implementazione si basa internamente su
@sinonjs/fake-timers
.TIP
Dalla versione
0.35.0
vi.useFakeTimers()
non simula più automaticamenteprocess.nextTick
. Può comunque essere simulato (mocked) specificando l'opzione nell'argomentotoFake
:vi.useFakeTimers({ toFake: ['nextTick'] })
.
vi.isFakeTimers
Tipo:
() => boolean
Versione: Da Vitest 0.34.5
Restituisce
true
se i fake timers sono abilitati.
vi.useRealTimers
Tipo:
() => Vitest
Quando si desidera disabilitare i timer fittizi, è possibile chiamare questo metodo per ripristinare i timer simulati (mocked) alle loro implementazioni originali. Tutti i timer che sono stati eseguiti in precedenza non verranno ripristinati.
vi.waitFor
- Tipo:
<T>(callback: WaitForCallback<T>, options?: number | WaitForOptions) => Promise<T>
- Versione: Da Vitest 0.34.5
Attende che la callback venga eseguita con successo. Se la callback genera un errore o restituisce una promise rifiutata, continuerà ad attendere fino al raggiungimento del successo o dello scadere del timeout.
Questo è molto utile quando è necessario attendere il completamento di un'azione asincrona. Ad esempio, quando si avvia un server e si deve attendere che sia pronto.
import { expect, test, vi } from 'vitest';
import { createServer } from './server.js';
test('Server avviato correttamente', async () => {
const server = createServer();
await vi.waitFor(
() => {
if (!server.isReady) throw new Error('Server non avviato');
console.log('Server avviato');
},
{
timeout: 500, // il valore predefinito è 1000
interval: 20, // il valore predefinito è 50
}
);
expect(server.isReady).toBe(true);
});
Funziona anche per le callback asincrone
// @vitest-environment jsdom
import { expect, test, vi } from 'vitest';
import { getDOMElementAsync, populateDOMAsync } from './dom.js';
test('Elemento esistente in un DOM', async () => {
// inizia a popolare il DOM
populateDOMAsync();
const element = await vi.waitFor(
async () => {
// prova a ottenere l'elemento finché non esiste
const element = (await getDOMElementAsync()) as HTMLElement | null;
expect(element).toBeTruthy();
expect(element.dataset.initialized).toBeTruthy();
return element;
},
{
timeout: 500, // il valore predefinito è 1000
interval: 20, // il valore predefinito è 50
}
);
expect(element).toBeInstanceOf(HTMLElement);
});
Se viene utilizzato vi.useFakeTimers
, vi.waitFor
chiama automaticamente vi.advanceTimersByTime(interval)
in ogni funzione di callback.
vi.waitUntil
- Tipo:
<T>(callback: WaitUntilCallback<T>, options?: number | WaitUntilOptions) => Promise<T>
- Versione: Da Vitest 0.34.5
Questo è simile a vi.waitFor
, ma se la callback genera errori, l'esecuzione viene interrotta immediatamente e viene sollevato un errore. Se la callback restituisce un valore falsy, il controllo successivo continuerà fino a quando non viene restituito un valore truthy. Questo è utile quando è necessario attendere che qualcosa esista prima di poter procedere con il passo successivo.
Si consideri l'esempio seguente. Possiamo usare vi.waitUntil
per attendere che l'elemento appaia sulla pagina, e poi possiamo interagire con l'elemento.
import { expect, test, vi } from 'vitest';
test('Elemento renderizzato correttamente', async () => {
const element = await vi.waitUntil(() => document.querySelector('.element'), {
timeout: 500, // il valore predefinito è 1000
interval: 20, // il valore predefinito è 50
});
// fare qualcosa con l'elemento
expect(element.querySelector('.element-child')).toBeTruthy();
});