Skip to content
Vitest 1
Main Navigation GuidaAPIConfigurazioneAvanzato
1.6.1
0.34.6

Italiano

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

Italiano

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

Aspetto

Sidebar Navigation

Guida

Perché Vitest

Introduzione

Funzionalità

Workspace

Interfaccia a riga di comando

Filtro dei test

Reporter

Coverage

Snapshot

Mocking

Test dei Tipi

Interfaccia Utente di Vitest

Modalità Browser

Test nel codice sorgente

Contesto del Test

Ambienti di Test

Estensione dei Matchers

Integrazione con gli IDE

Debugging

Confronti con altri Test Runner

Guida alla Migrazione

Errori Frequenti

Ottimizzare le Prestazioni

API

Riferimento API Test

Funzioni Mock

Vi

expect

expectTypeOf

assert

assertType

Configurazione

Gestione del file di configurazione di Vitest

Configurazione di Vitest

In questa pagina

Vi ​

Vitest fornisce funzioni di utilità tramite l'helper vi. Puoi accedervi globalmente (quando la configurazione dei globals è abilitata), oppure importarlo direttamente da vitest:

js
import { vi } from 'vitest';

Mock dei Moduli ​

Questa sezione descrive l'API che puoi usare per il mocking di un modulo. Tieni presente che Vitest non supporta il mocking di moduli importati con require().

vi.mock ​

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

Sostituisce tutti i moduli importati dal percorso specificato con un altro modulo. Puoi usare gli alias Vite configurati all'interno del percorso. La chiamata a vi.mock subisce l'hoisting, quindi non importa dove la chiami, sarà sempre eseguita prima di tutti gli import. Se hai bisogno di fare riferimento a variabili al di fuori del suo scope, puoi definirle all'interno di vi.hoisted e farvi riferimento in vi.mock.

WARNING

vi.mock funziona solo per i moduli importati con la parola chiave import. Non funziona con require.

Per consentire l'hoisting di vi.mock, Vitest analizza staticamente i file. Questo significa che vi, se non importato direttamente dal pacchetto vitest (ad esempio, da un file di utilità), non può essere usato. Usa vi.mock con vi importato da vitest, oppure abilita l'opzione di configurazione globals.

Vitest non effettuerà il mock dei moduli importati all'interno di un file di setup perché sono memorizzati nella cache nel momento in cui un file di test è in esecuzione. Puoi chiamare vi.resetModules() all'interno di vi.hoisted per cancellare tutte le cache dei moduli prima di eseguire un file di test.

WARNING

La modalità browser attualmente non supporta il mocking dei moduli. Puoi seguire lo stato di questa funzionalità nella issue su GitHub.

Se factory è definito, tutti gli import restituiranno il suo risultato. Vitest chiama la factory solo una volta e memorizza nella cache i risultati per tutti gli import successivi fino a quando non viene chiamato vi.unmock o vi.doUnmock.

A differenza di jest, la factory può essere una funzione asincrona. Puoi usare vi.importActual o un helper con la factory passata come primo argomento, e ottenere il modulo originale al suo interno.

js
import { vi } from 'vitest';
// ---cut---
// quando si usa JavaScript

vi.mock('./path/to/module.js', async importOriginal => {
  const mod = await importOriginal();
  return {
    ...mod,
    // sostituisci alcune esportazioni
    namedExport: vi.fn(),
  };
});
ts
// quando si usa TypeScript

vi.mock('./path/to/module.js', async importOriginal => {
  const mod = await importOriginal<typeof import('./path/to/module.js')>();
  return {
    ...mod,
    // sostituisci alcune esportazioni
    namedExport: vi.fn(),
  };
});

WARNING

vi.mock subisce l'hoisting (ovvero, viene spostato) all'inizio del file. Questo significa che ogni volta che lo scrivi (che sia all'interno di beforeEach o test), sarà effettivamente chiamato prima di tutto.

Significa anche che non è possibile usare variabili all'interno della factory che siano definite al di fuori di essa.

Se hai bisogno di usare variabili all'interno della factory, prova vi.doMock. Funziona allo stesso modo ma non viene hoisted. Nota che effettua il mock solo degli import successivi.

Puoi anche fare riferimento a variabili definite con il metodo vi.hoisted se è stato dichiarato prima di 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

Se stai mockando un modulo con export di default, è necessario fornire una chiave default all'interno dell'oggetto restituito dalla factory. Questa è un'avvertenza specifica dei moduli ES; pertanto, la documentazione di jest potrebbe differire poiché jest usa moduli CommonJS. Per esempio,

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

Se c'è una cartella __mocks__ accanto a un file di cui stai facendo il mock, e la factory non è fornita, Vitest proverà a trovare un file con lo stesso nome nella sottocartella __mocks__ e lo userà come modulo effettivo. Se stai mockando una dipendenza, Vitest proverà a trovare una cartella __mocks__ nella root del progetto (il default è process.cwd()). Puoi indicare a Vitest dove si trovano le dipendenze tramite l'opzione di configurazione deps.moduleDirectories.

Per 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 una factory fornita, troverà un file nella cartella __mocks__ da usare come modulo:

ts
// increment.test.js
import { vi } from 'vitest';

// axios è un export di default da `__mocks__/axios.js`
import axios from 'axios';

// increment è un export con nome 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 mockati automaticamente. Per replicare il comportamento di automocking di Jest, puoi chiamare vi.mock per ogni modulo richiesto all'interno di setupFiles.

Se non c'è una cartella __mocks__ o una factory fornita, Vitest importerà il modulo originale e farà l'auto-mock di tutti i suoi export. Per le regole applicate, vedi algoritmo.

vi.doMock ​

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

Come vi.mock, ma non viene hoisted all'inizio del file, quindi puoi fare riferimento a variabili nello scope globale del file. Il successivo import dinamico del modulo verrà mockato.

WARNING

Questo non mocka i moduli che sono stati importati prima di questa chiamata. Non dimenticare che tutti gli import statici in ESM sono sempre hoisted, quindi mettere questo prima dell'import static non forzerà la sua chiamata prima dell'import:

ts
vi.doMock('./increment.js'); // questo sarà chiamato _dopo_ l'istruzione 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';

// il modulo non viene mockato, perché vi.doMock non è stato ancora 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 MOCKATO, perché vi.doMock è valutato DOPO gli import
  expect(increment(1)).toBe(2);
  const { increment: mockedIncrement } = await import('./increment.js');
  // il nuovo import dinamico restituisce il modulo mockato
  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>

Helper di tipo per TypeScript. Restituisce semplicemente l'oggetto passato come argomento.

Quando partial è true si aspetterà un Partial<T> come valore di ritorno. Di default, questo farà solo credere a TypeScript che i valori del primo livello siano mockati. Puoi passare { deep: true } come secondo argomento per dire a TypeScript che l'intero oggetto è mockato, se lo è effettivamente.

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

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

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

vi.importActual ​

  • Tipo: <T>(path: string) => Promise<T>

Importa il modulo, bypassando tutti i controlli che verificherebbero se dovrebbe essere mockato. Può essere utile se vuoi mockare il modulo parzialmente.

ts
vi.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à annidate) mockate. Segue le stesse regole di vi.mock. Per le regole applicate, vedi algoritmo.

vi.unmock ​

  • Tipo: (path: string) => void

Rimuove il modulo dal registro dei mock. Tutte le chiamate a import restituiranno il modulo originale anche se era stato mockato prima. Questa chiamata subisce l'hoisting all'inizio del file, quindi effettuerà l'unmock solo dei moduli definiti, ad esempio, nei setupFiles.

vi.doUnmock ​

  • Tipo: (path: string) => void

Come vi.unmock, ma non viene hoisted all'inizio del file. Il prossimo import del modulo importerà il modulo originale invece del mock. Questo non effettua l'unmock dei moduli importati precedentemente.

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

// increment è già mockato, perché vi.mock è hoisted
increment(1) === 100;

// questo è hoisted, e la factory viene chiamata prima dell'import alla riga 1
vi.mock('./increment.js', () => ({ increment: () => 100 }));

// tutte le chiamate sono mockate, e `increment` restituisce sempre 100
increment(1) === 100;
increment(30) === 100;

// questo non è hoisted, quindi l'altro import restituirà il modulo non mockato
vi.doUnmock('./increment.js');

// questo RESTITUISCE ANCORA 100, perché `vi.doUnmock` non rivaluta un modulo
increment(1) === 100;
increment(30) === 100;

// il prossimo import non è mockato, ora `increment` è la funzione originale che restituisce count + 1
const { increment: unmockedIncrement } = await import('./increment.js');

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

vi.resetModules ​

  • Tipo: () => Vitest

Resetta il registro dei moduli cancellando la cache di tutti i moduli. Questo permette ai moduli di essere rivalutati quando vengono reimportati. Le importazioni di primo livello non possono essere rivalutate. Può essere utile per isolare i moduli in cui lo stato locale è in conflitto tra i test.

ts
import { 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 resetta il registro dei mock. Per cancellare il registro dei mock, usa vi.unmock o vi.doUnmock.

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.

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

// non posso tracciare l'import perché Promise non viene restituita
function renderComponent() {
  import('./component.js').then(({ render }) => {
    render();
  });
}

test('operations are resolved', async () => {
  renderComponent();
  await vi.dynamicImportSettled();
  expect(document.querySelector('.component')).not.toBeNull();
});

TIP

Se durante un import dinamico viene avviato un altro import dinamico, questo metodo aspetterà che tutti siano risolti.

Questo metodo aspetterà anche il prossimo tick di setTimeout dopo che l'import è stato risolto, quindi tutte le operazioni sincrone dovrebbero essere completate nel momento in cui viene risolto.

Mocking di Funzioni e Oggetti ​

Questa sezione descrive come lavorare con i mock dei metodi e sostituire le variabili ambientali e globali.

vi.fn ​

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

Crea uno spy su una funzione, ma può essere usata anche senza una funzione di partenza. Ogni volta che una funzione viene invocata, memorizza i suoi argomenti di chiamata, i valori di ritorno e le istanze. Inoltre, puoi manipolare il suo comportamento con i metodi. Se non viene fornita alcuna funzione, il mock restituirà undefined quando invocato.

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 ​

  • Tipo: (fn: Function) => boolean

Controlla se un dato parametro è una funzione mock. Se si utilizza TypeScript, restringerà anche il suo tipo.

vi.clearAllMocks ​

Chiama .mockClear() su tutti gli spy. Questo cancellerà la cronologia dei mock, ma non ripristinerà l'implementazione predefinita.

vi.resetAllMocks ​

Chiama .mockReset() su tutti gli spy. Questo cancellerà la cronologia dei mock e ripristinerà l'implementazione a una funzione vuota (che restituirà undefined).

vi.restoreAllMocks ​

Chiama .mockRestore() su tutti gli spy. Questo cancellerà la cronologia dei mock e ripristinerà l'implementazione originale.

vi.spyOn ​

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

Crea uno spy su un metodo o getter/setter di un oggetto, in modo simile a vi.fn(). Restituisce una funzione mock.

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

Puoi chiamare vi.restoreAllMocks all'interno di afterEach (o abilitare test.restoreMocks) per ripristinare tutti i metodi alle loro implementazioni originali. Questo ripristinerà il descrittore dell'oggetto originale, quindi non sarai in grado di cambiare l'implementazione del metodo:

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()); // ancora 42!

vi.stubEnv 0.26.0+ ​

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

Modifica il valore della variabile d'ambiente in process.env e import.meta.env. Puoi ripristinare il suo valore chiamando vi.unstubAllEnvs.

ts
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 altre variabili d'ambiente
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:

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

vi.unstubAllEnvs 0.26.0+ ​

  • Tipo: () => Vitest

Ripristina tutti i valori di import.meta.env e process.env modificati con vi.stubEnv. Quando viene chiamato per la prima volta, Vitest ricorda il valore originale e lo memorizzerà, fino a quando unstubAllEnvs non viene chiamato di nuovo.

ts
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 al valore che è stato memorizzato prima della prima chiamata "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 della variabile globale. Puoi ripristinare il suo valore originale chiamando vi.unstubAllGlobals.

ts
import { vi } from 'vitest';

// `innerWidth` ha valore "0" prima di chiamare stubGlobal

vi.stubGlobal('innerWidth', 100);

innerWidth === 100;
globalThis.innerWidth === 100;
// se stai usando jsdom o happy-dom
window.innerWidth === 100;

TIP

Puoi anche cambiare il valore semplicemente assegnandolo a globalThis o window (se stai usando l'ambiente jsdom o happy-dom), ma non sarai in grado di usare vi.unstubAllGlobals per ripristinare il valore originale:

ts
globalThis.innerWidth = 100;
// se stai usando jsdom o happy-dom
window.innerWidth = 100;

vi.unstubAllGlobals 0.26.0+ ​

  • Tipo: () => Vitest

Ripristina tutti i valori globali di globalThis/global (e window/top/self/parent, se si utilizza l'ambiente jsdom o happy-dom) modificati con vi.stubGlobal. Quando viene chiamato per la prima volta, Vitest ricorda il valore originale e lo memorizzerà, fino a quando unstubAllGlobals non viene chiamato di nuovo.

ts
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 stai usando jsdom o happy-dom
window.IntersectionObserver === Mock;

vi.unstubAllGlobals();

globalThis.IntersectionObserver === undefined;
'IntersectionObserver' in globalThis === false;
// lancia ReferenceError, perché non è definito
IntersectionObserver === undefined;

Timer Fittizi ​

Questa sezione descrive come lavorare con i timer fittizi.

vi.advanceTimersByTime ​

  • Tipo: (ms: number) => Vitest

Questo metodo avanza i timer simulati del numero specificato di millisecondi (ms). Esegue tutti i timer in attesa fino a quando non è trascorso il tempo specificato o fino a quando la coda dei timer non è vuota, a seconda di quale condizione si verifica prima.

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 ​

  • Tipo: (ms: number) => Promise<Vitest>

Simile a vi.advanceTimersByTime, ma gestisce anche i timer impostati in modo asincrono. Avanza i timer simulati del numero specificato di millisecondi (ms), eseguendo tutti i timer in attesa, inclusi quelli asincroni, fino a quando non è trascorso il tempo specificato o fino a quando la coda dei timer non è vuota.

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 ​

  • Tipo: () => Vitest

Esegue il timer successivo disponibile nella coda. Utile per eseguire asserzioni tra le singole esecuzioni dei timer. Puoi concatenare le chiamate per controllare manualmente l'esecuzione dei timer.

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 ​

  • Tipo: () => Promise<Vitest>

Esegue il timer successivo disponibile nella coda, gestendo anche i timer asincroni. Attende che il timer venga risolto se è stato impostato in modo asincrono. Utile per eseguire asserzioni tra le singole esecuzioni dei timer.

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 ​

  • Tipo: () => number

Restituisce il numero di timer attualmente in attesa di esecuzione.

vi.clearAllTimers ​

Rimuove tutti i timer programmati, impedendone l'esecuzione futura.

vi.getMockedSystemTime ​

  • Tipo: () => Date | null

Restituisce la data corrente simulata impostata tramite vi.setSystemTime. Se la data non è stata simulata, il metodo restituisce null.

vi.getRealSystemTime ​

  • Tipo: () => number

Quando si utilizza vi.useFakeTimers, le chiamate a Date.now vengono simulate. Se è necessario ottenere il timestamp reale in millisecondi, è possibile chiamare questa funzione.

vi.runAllTicks ​

  • Tipo: () => Vitest

Esegue tutte le microtask messe in coda da process.nextTick. Questo eseguirà anche tutte le microtask pianificate da esse.

vi.runAllTimers ​

  • Tipo: () => Vitest

Esegue tutti i timer impostati fino a quando la coda dei timer non è vuota. Ciò significa che tutti i timer chiamati durante l'esecuzione di vi.runAllTimers verranno eseguiti. Se è presente un intervallo infinito, verrà generata un'eccezione dopo 10.000 tentativi (configurabile tramite 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 ​

  • Tipo: () => Promise<Vitest>

Esegue in modo asincrono tutti i timer impostati fino a quando la coda dei timer non è vuota. Ciò significa che tutti i timer chiamati durante l'esecuzione di vi.runAllTimersAsync, inclusi quelli asincroni, verranno eseguiti. Se è presente un intervallo infinito, verrà generata un'eccezione dopo 10.000 tentativi (configurabile tramite fakeTimers.loopLimit).

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

await vi.runAllTimersAsync();

// log: result

vi.runOnlyPendingTimers ​

  • Tipo: () => Vitest

Esegue tutti i timer che sono stati avviati dopo la chiamata a vi.useFakeTimers. Non eseguirà alcun timer avviato durante la sua esecuzione.

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

vi.runOnlyPendingTimers();

// log: 1

vi.runOnlyPendingTimersAsync ​

  • Tipo: () => Promise<Vitest>

Esegue in modo asincrono tutti i timer che sono stati avviati dopo la chiamata a vi.useFakeTimers, inclusi quelli asincroni. Non eseguirà alcun timer avviato durante la sua esecuzione.

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 ​

  • Tipo: (date: string | number | Date) => void

Se i timer fittizi sono abilitati, questo metodo simula la modifica dell'orologio di sistema da parte di un utente (influenzando le API che lavorano con le date come hrtime, performance.now o new Date()); tuttavia, non eseguirà alcun timer. Se i timer fittizi non sono abilitati, questo metodo simulerà solo le chiamate a Date.*.

Utile per testare codice che dipende dalla data corrente, ad esempio le chiamate a Luxon all'interno del codice.

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 ​

  • Tipo: (config?: FakeTimerInstallOpts) => Vitest

Per abilitare la simulazione dei timer, è necessario chiamare questo metodo. Intercetta tutte le chiamate successive alle funzioni di gestione dei timer (come setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, clearImmediate e Date) fino a quando non viene chiamato vi.useRealTimers().

La simulazione di nextTick non è supportata quando si esegue Vitest all'interno di node:child_process utilizzando --pool=forks. NodeJS utilizza internamente process.nextTick in node:child_process e si blocca se viene simulato. La simulazione di nextTick è supportata quando si esegue Vitest con --pool=threads.

L'implementazione si basa internamente su @sinonjs/fake-timers.

TIP

Dalla versione 0.35.0 vi.useFakeTimers() non simula più automaticamente process.nextTick. Può comunque essere simulato specificando l'opzione nell'argomento toFake: vi.useFakeTimers({ toFake: ['nextTick'] }).

vi.isFakeTimers 0.34.5+ ​

  • Tipo: () => boolean

Restituisce true se i timer fittizi sono abilitati.

vi.useRealTimers ​

  • Tipo: () => Vitest

Dopo aver utilizzato i timer simulati, è possibile chiamare questo metodo per ripristinare le implementazioni originali dei timer. Tutti i timer programmati in precedenza verranno scartati.

Varie ​

Un insieme di funzioni di utilità fornite da Vitest.

vi.waitFor 0.34.5+ ​

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

Attende che la callback venga eseguita correttamente. Se la callback genera un errore o restituisce una promessa rifiutata, continuerà ad attendere finché non avrà successo o fino a quando non scadrà il timeout.

Questo è molto utile quando è necessario attendere il completamento di un'azione asincrona, ad esempio, quando si avvia un server ed è necessario attendere che sia pronto.

ts
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 default è 1000
      interval: 20, // il default è 50
    }
  );
  expect(server.isReady).toBe(true);
});

Funziona anche per le callback asincrone

ts
// @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 fino a quando non viene trovato
      const element = (await getDOMElementAsync()) as HTMLElement | null;
      expect(element).toBeTruthy();
      expect(element.dataset.initialized).toBeTruthy();
      return element;
    },
    {
      timeout: 500, // il default è 1000
      interval: 20, // il default è 50
    }
  );
  expect(element).toBeInstanceOf(HTMLElement);
});

Se viene utilizzato vi.useFakeTimers, vi.waitFor chiama automaticamente vi.advanceTimersByTime(interval) ad ogni esecuzione della callback.

vi.waitUntil 0.34.5+ ​

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

Simile a vi.waitFor, ma se la callback genera un errore, l'esecuzione viene immediatamente interrotta e si riceverà 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 procedere con il passo successivo.

Guarda l'esempio qui sotto. Possiamo usare vi.waitUntil per attendere che l'elemento appaia nella pagina, e poi possiamo fare qualcosa con l'elemento.

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

test('Elemento renderizzato correttamente', async () => {
  const element = await vi.waitUntil(() => document.querySelector('.element'), {
    timeout: 500, // il default è 1000
    interval: 20, // il default è 50
  });

  // fare qualcosa con l'elemento
  expect(element.querySelector('.element-child')).toBeTruthy();
});

vi.hoisted 0.31.0+ ​

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

Tutte le istruzioni import statiche nei moduli ES vengono hoistate all'inizio del file, quindi qualsiasi codice definito prima degli import verrà effettivamente eseguito dopo che gli import sono stati valutati.

Tuttavia, può essere utile invocare alcuni effetti collaterali come la simulazione delle date prima di importare un modulo.

Per ovviare a questa limitazione, puoi riscrivere gli import statici in import dinamici in questo modo:

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

Quando si esegue vitest, è possibile farlo automaticamente utilizzando il metodo vi.hoisted.

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

Questo metodo restituisce il valore restituito dalla factory. Puoi usare quel valore nelle tue factory vi.mock se hai bisogno di un facile accesso alle variabili definite localmente:

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

Nota che questo metodo può anche essere chiamato in modo asincrono anche se il tuo ambiente non supporta l'attesa di livello superiore (top-level await):

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

vi.setConfig ​

  • Tipo: RuntimeConfig

Aggiorna la configurazione del file di test corrente. Questo metodo supporta solo le opzioni di configurazione che hanno effetto sul file di test corrente:

ts
vi.setConfig({
  allowOnly: true,
  testTimeout: 10_000,
  hookTimeout: 10_000,
  clearMocks: true,
  restoreMocks: true,
  fakeTimers: {
    now: new Date(2021, 11, 19),
    // supporta l'intero oggetto
  },
  maxConcurrency: 10,
  sequence: {
    hooks: 'stack',
    // supporta solo "sequence.hooks"
  },
});

vi.resetConfig ​

  • Tipo: RuntimeConfig

Se vi.setConfig è stato chiamato in precedenza, questo riporterà la configurazione allo stato originale.

Pager
Pagina precedenteFunzioni Mock
Pagina successivaexpect

Rilasciato sotto la licenza MIT.

Copyright (c) 2024 Mithril Contributors

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

Rilasciato sotto la licenza MIT.

Copyright (c) 2024 Mithril Contributors