Skip to content
Vitest 3
Main Navigation Guida & APIConfigurazioneModalità BrowserAPI avanzata
3.2.0
2.1.9
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

Introduzione

Perché Vitest

Per Iniziare

Caratteristiche

Configurazione di Vitest

API

Riferimento API di test

Funzioni Mock

Vi

expect

expectTypeOf

assert

assertType

Guida

Interfaccia a Riga di Comando

Filtro dei Test

Progetti di Test

Reporter

Copertura

Snapshot

Mocking

Parallelismo

Tipi di Test

Vitest UI

Test nel Codice Sorgente

Contesto di Test

Annotazioni dei Test

Ambiente di Test

Estensione dei Matcher

Integrazioni IDE

Debugging

Errori Comuni

Guida alla Migrazione

Migrazione a Vitest 3.0

Migrazione da Jest

Prestazioni

Profilazione delle prestazioni dei test

Ottimizzare le Prestazioni

Modalità Browser

API Avanzate

Confronto con Altri Test Runner

In questa pagina

Vi ​

Vitest mette a disposizione funzioni di utilità tramite il suo helper vi. È accessibile globalmente (quando la configurazione globale è abilitata), oppure puoi importarlo direttamente da vitest:

js
import { vi } from 'vitest';

Moduli Mock ​

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

vi.mock ​

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

Sostituisce tutti i moduli importati dal percorso fornito con un altro modulo. Puoi usare gli alias Vite configurati all'interno di un percorso. La chiamata a vi.mock viene sollevata (hoisted), quindi non importa dove la si chiami: verrà sempre eseguita prima di tutte le importazioni. Se hai bisogno di fare riferimento a variabili al di fuori del suo ambito, puoi definirle all'interno di vi.hoisted e farvi riferimento all'interno di vi.mock.

WARNING

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

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

Vitest non moccherà i moduli che sono stati importati all'interno di un file di setup perché vengono 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.

Se la funzione factory è definita, tutte le importazioni restituiranno il suo risultato. Vitest chiama la factory una sola volta e memorizza nella cache i risultati per tutte le importazioni successive finché non viene chiamato vi.unmock o vi.doUnmock.

A differenza di jest, la factory può essere anche asincrona. Puoi usare vi.importActual o un helper con la factory passata come primo argomento, per ottenere il modulo originale all'interno.

Puoi anche fornire un oggetto con una proprietà spy al posto di una funzione factory. Se spy è true, Vitest automoccherà il modulo come di consueto, ma non sovrascriverà l'implementazione degli export. Questo è utile se desideri solo verificare che il metodo esportato sia stato chiamato correttamente da un altro metodo.

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

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

// chiama l'implementazione originale,
// ma permette di asserire il comportamento in seguito
const result = calculator(1, 2);

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

Vitest supporta anche una Promise di modulo invece di una stringa nei metodi vi.mock e vi.doMock per un migliore supporto IDE. Quando il file viene spostato, il percorso verrà aggiornato e importOriginal erediterà automaticamente il tipo. L'uso di questa firma imporrà anche che il tipo di ritorno della factory sia compatibile con il modulo originale (mantenendo gli export opzionali).

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(); // il tipo è inferito
  //    ^?
  return {
    ...mod,
    // sostituisce alcuni export
    total: vi.fn(),
  };
});

Sotto il cofano, Vitest opera ancora su una stringa e non su un oggetto modulo.

Se utilizzi TypeScript con alias paths configurati in tsconfig.json, tuttavia, il compilatore non sarà in grado di risolvere correttamente i tipi di importazione. Per farlo funzionare, assicurati di sostituire tutte le importazioni con alias con i loro percorsi relativi corrispondenti. Es. usa import('./path/to/module.js') invece di import('@/module').

WARNING

vi.mock viene sollevato (in altre parole, spostato) in cima al file. Ciò significa che ogni volta che lo si scrive (sia all'interno di beforeEach o test), verrà effettivamente chiamato prima di quello.

Ciò significa anche che non è possibile usare variabili all'interno della factory che sono definite al di fuori della factory.

Se hai bisogno di utilizzare variabili all'interno della factory, prova vi.doMock. Funziona allo stesso modo ma non viene sollevato. Fai attenzione che fa il mock solo delle importazioni successive.

Puoi anche fare riferimento a variabili definite dal 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 mocando un modulo con un export predefinito, dovrai fornire una chiave default all'interno dell'oggetto della funzione factory restituita. Questa è una particolarità specifica dei moduli ES; pertanto, la documentazione di jest potrebbe differire poiché jest utilizza moduli CommonJS. Ad esempio,

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

Se c'è una cartella __mocks__ accanto a un file di cui stai mocando, e la factory non è fornita, Vitest cercherà di trovare un file con lo stesso nome nella sottocartella __mocks__ e lo userà come modulo effettivo. Se stai mocando una dipendenza, Vitest cercherà una cartella __mocks__ nella root del progetto (il valore predefinito è process.cwd()). Puoi dire 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 una factory o opzioni fornite, troverà un file nella cartella __mocks__ da usare come modulo:

ts
import { vi } from 'vitest';

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

// increment è un export nominato da `src/__mocks__/increment.js`
import { increment } from '../increment.js';

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

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

WARNING

Tieni presente che se non chiami vi.mock, i moduli non vengono automaticamente mockati. 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 automoccherà tutti i suoi export. Per le regole applicate, vedi algoritmo.

vi.doMock ​

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

Uguale a vi.mock, ma non viene sollevato in cima al file, quindi puoi fare riferimento a variabili nello scope del file globale. La prossima importazione dinamica del modulo verrà mockata.

WARNING

Questo non moccherà i moduli che sono stati importati prima che questo fosse chiamato. Non dimenticare che tutte le importazioni statiche in ESM sono sempre sollevate, quindi posizionare questo prima dell'importazione statica non la forzerà a essere chiamata prima dell'importazione:

ts
vi.doMock('./increment.js'); // questo verrà chiamato _dopo_ l'istruzione import

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

// il modulo non è mockato, 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('l\'importazione del modulo successivo importa quello mockato', async () => {
  // l'importazione originale NON È STATA MOCKATA, perché vi.doMock viene valutato DOPO le importazioni
  expect(increment(1)).toBe(2);
  const { increment: mockedIncrement } = await import('./increment.js');
  // la nuova importazione dinamica 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 che è stato passato.

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

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

test('valore di ritorno mockato con tipizzazione solo parzialmente corretta', 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 }) // questo è un errore di tipo
});

vi.importActual ​

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

Importa il modulo, bypassando tutti i controlli se deve essere mockato. Può essere utile se si desidera mocare il modulo parzialmente.

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

  return { ...originalModule, 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 | Promise<Module>) => void

Rimuove il modulo dal registro dei mock. Tutte le chiamate di importazione restituiranno il modulo originale anche se era stato mockato in precedenza. Questa chiamata viene sollevata in cima al file, quindi smoccherà solo i moduli che sono stati definiti in setupFiles, ad esempio.

vi.doUnmock ​

  • Tipo: (path: string | Promise<Module>) => void

Uguale a vi.unmock, ma non viene sollevato in cima al file. La prossima importazione del modulo importerà il modulo originale invece del mock. Questo non smoccherà i moduli importati in precedenza.

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

// increment è già mockato, 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 mockate, e `increment` restituisce sempre 100
increment(1) === 100;
increment(30) === 100;

// questo non è sollevato, quindi un'altra importazione restituirà un modulo non mockato
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 è mockata, 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. Ciò consente ai moduli di essere rivalutati quando vengono reimportati. Le importazioni di primo livello non possono essere rivalutate. Potrebbe 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('cambia stato', async () => {
  const mod = await import('./some/path.js'); // Verrà rivalutato
  mod.changeLocalState('nuovo valore');
  expect(mod.getLocalState()).toBe('nuovo valore');
});

test('il modulo ha il vecchio stato', async () => {
  const mod = await import('./some/path.js'); // Verrà rivalutato
  expect(mod.getLocalState()).toBe('vecchio valore');
});

WARNING

Non resetta il registro dei mock. Per cancellare il registro dei mock, usa vi.unmock o vi.doUnmock.

vi.dynamicImportSettled ​

Attende il caricamento di tutte le importazioni dinamiche. Utile se si ha una chiamata sincrona che avvia l'importazione di un modulo che altrimenti non si potrebbe attendere.

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

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

test('le operazioni sono risolte', async () => {
  renderComponent();
  await vi.dynamicImportSettled();
  expect(document.querySelector('.component')).not.toBeNull();
});

TIP

Se durante un'importazione dinamica viene avviata un'altra importazione dinamica, questo metodo attenderà che tutte siano risolte.

Questo metodo attenderà anche il prossimo tick di setTimeout dopo che l'importazione è stata risolta, in modo che tutte le operazioni sincrone siano completate al momento della sua risoluzione.

Mocking di Funzioni e Oggetti ​

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

vi.fn ​

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

Crea una spia su una funzione, sebbene possa essere avviata senza una. Ogni volta che una funzione viene invocata, memorizza i suoi argomenti di chiamata, i valori di ritorno e le istanze. Inoltre, è possibile manipolare il suo comportamento con i metodi. Se non viene fornita alcuna funzione, il mock restituirà undefined quando invocato.

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

  • Tipo: <T>(value: T) => MaybeMockedDeep<T>

Mocca profondamente le proprietà e i metodi di un dato oggetto nello stesso modo in cui vi.mock() mocca gli export dei moduli. Per i dettagli, consultare automocking.

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 ​

  • Tipo: (fn: Function) => boolean

Verifica che un dato parametro sia una funzione mock. Se stai usando TypeScript, restringerà anche il suo tipo.

vi.clearAllMocks ​

Chiama .mockClear() su tutte le spie. Questo cancellerà la cronologia dei mock senza influenzare le implementazioni dei mock.

vi.resetAllMocks ​

Chiama .mockReset() su tutte le spie. Questo cancellerà la cronologia dei mock e resetterà l'implementazione di ogni mock alla sua originale.

vi.restoreAllMocks ​

Chiama .mockRestore() su tutte le spie. Questo cancellerà la cronologia dei mock, ripristinerà tutte le implementazioni originali dei mock e ripristinerà i descrittori originali degli oggetti spiati.

vi.spyOn ​

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

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

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

Negli ambienti che supportano la Gestione Esplicita delle Risorse, puoi usare using invece di const per chiamare automaticamente mockRestore su qualsiasi funzione mockata quando il blocco contenitore viene chiuso. Questo è particolarmente utile per i metodi spiati:

ts
it('chiama console.log', () => {
  using spy = vi.spyOn(console, 'log').mockImplementation(() => {})
  debug('messaggio')
  expect(spy).toHaveBeenCalled()
})
// console.log viene ripristinato qui

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 sarà possibile modificare 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!

TIP

Non è possibile spiare i metodi esportati in Modalità Browser. Invece, puoi spiare ogni metodo esportato chiamando vi.mock("./file-path.js", { spy: true }). Questo moccherà ogni export ma manterrà la sua implementazione intatta, permettendoti di asserire se il metodo è stato chiamato correttamente.

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

E sebbene sia possibile spiare gli export in jsdom o altri ambienti Node.js, questo potrebbe cambiare in futuro.

vi.stubEnv ​

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

Modifica il valore della variabile d'ambiente su 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';

vi.stubEnv('NODE_ENV', undefined);

process.env.NODE_ENV === undefined;
import.meta.env.NODE_ENV === undefined;

// 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:

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

vi.unstubAllEnvs ​

  • Tipo: () => Vitest

Ripristina tutti i valori di import.meta.env e process.env che sono stati modificati con vi.stubEnv. Quando viene chiamato per la prima volta, Vitest ricorda il valore originale e lo memorizzerà, finché unstubAllEnvs non verrà 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 era 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 di una variabile globale. Puoi ripristinare il suo valore originale chiamando vi.unstubAllGlobals.

ts
import { vi } from 'vitest';

// `innerWidth` è "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 ​

  • Tipo: () => Vitest

Ripristina tutti i valori globali su globalThis/global (e window/top/self/parent, se stai usando l'ambiente jsdom o happy-dom) che sono stati modificati con vi.stubGlobal. Quando viene chiamato per la prima volta, Vitest ricorda il valore originale e lo memorizzerà, finché unstubAllGlobals non verrà 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 invocherà ogni timer avviato finché non sarà trascorso il numero specificato di millisecondi o la coda sarà vuota - a seconda di quale condizione si verifichi per prima.

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

vi.advanceTimersByTime(150);

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

vi.advanceTimersByTimeAsync ​

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

Questo metodo invocherà ogni timer avviato finché non sarà trascorso il numero specificato di millisecondi o la coda sarà vuota - a seconda di quale condizione si verifichi per prima. Questo includerà i timer impostati in modo asincrono.

ts
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

Chiamerà il prossimo timer disponibile. Utile per effettuare asserzioni tra ogni chiamata del timer. Puoi concatenare le chiamate per gestire i timer autonomamente.

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

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

vi.advanceTimersToNextTimerAsync ​

  • Tipo: () => Promise<Vitest>

Chiamerà il prossimo timer disponibile e attenderà che sia risolto se è stato impostato in modo asincrono. Utile per effettuare asserzioni tra ogni chiamata del timer.

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

  • Tipo: () => Vitest

Simile a vi.advanceTimersByTime, ma farà avanzare i timer dei millisecondi necessari per eseguire i callback attualmente programmati con requestAnimationFrame.

ts
let frameRendered = false;

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

vi.advanceTimersToNextFrame();

expect(frameRendered).toBe(true);

vi.getTimerCount ​

  • Tipo: () => number

Ottiene il numero di timer in attesa.

vi.clearAllTimers ​

Rimuove tutti i timer programmati per l'esecuzione. Questi timer non verranno mai eseguiti in futuro.

vi.getMockedSystemTime ​

  • Tipo: () => Date | null

Restituisce la data corrente moccata. Se la data non è moccata, il metodo restituirà null.

vi.getRealSystemTime ​

  • Tipo: () => number

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

vi.runAllTicks ​

  • Tipo: () => Vitest

Chiama ogni microtask che è stato messo in coda da process.nextTick. Questo eseguirà anche tutte le microtask programmate autonomamente.

vi.runAllTimers ​

  • Tipo: () => Vitest

Questo metodo invocherà ogni timer avviato finché la coda dei timer non sarà vuota. Ciò significa che ogni timer chiamato durante runAllTimers verrà attivato. Se si ha un intervallo infinito, lancerà un'eccezione dopo 10.000 tentativi (configurabile con fakeTimers.loopLimit).

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 ​

  • Tipo: () => Promise<Vitest>

Questo metodo invocherà in modo asincrono ogni timer avviato finché la coda dei timer non sarà vuota. Ciò significa che ogni timer chiamato durante runAllTimersAsync verrà attivato, inclusi i timer asincroni. Se si ha un intervallo infinito, lancerà un'eccezione dopo 10.000 tentativi (configurabile con fakeTimers.loopLimit).

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

await vi.runAllTimersAsync();

// log: result

vi.runOnlyPendingTimers ​

  • Tipo: () => Vitest

Questo metodo chiamerà ogni timer che è stato avviato dopo la chiamata a vi.useFakeTimers. Non attiverà alcun timer che è stato avviato durante la sua chiamata.

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

vi.runOnlyPendingTimers();

// log: 1

vi.runOnlyPendingTimersAsync ​

  • Tipo: () => Promise<Vitest>

Questo metodo chiamerà in modo asincrono ogni timer che è stato avviato dopo la chiamata a vi.useFakeTimers, inclusi quelli asincroni. Non attiverà alcun timer che è stato avviato durante la sua chiamata.

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 ​

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

Se i timer fittizi sono abilitati, questo metodo simula un utente che cambia l'orologio di sistema (influirà sulle API relative alla data come hrtime, performance.now o new Date()) - tuttavia, non attiverà alcun timer. Se i timer fittizi non sono abilitati, questo metodo moccherà solo le chiamate Date.*.

Utile se è necessario testare qualcosa che dipende dalla data corrente - ad esempio le chiamate Luxon all'interno del proprio codice.

Accetta gli stessi argomenti stringa e numerici di Date.

ts
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 il mocking dei timer, è necessario chiamare questo metodo. Avvolgerà tutte le chiamate successive ai timer (come setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, clearImmediate e Date) finché non verrà chiamato vi.useRealTimers().

Il mocking di nextTick non è supportato quando si esegue Vitest all'interno di node:child_process usando --pool=forks. NodeJS usa process.nextTick internamente in node:child_process e si blocca quando viene mockato. Il mocking di nextTick è supportato quando si esegue Vitest con --pool=threads.

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

TIP

vi.useFakeTimers() non mocca automaticamente process.nextTick e queueMicrotask. Ma è possibile abilitarlo specificando l'opzione nell'argomento toFake: vi.useFakeTimers({ toFake: ['nextTick', 'queueMicrotask'] }).

vi.isFakeTimers ​

  • Tipo: () => boolean

Restituisce true se i timer fittizi sono abilitati.

vi.useRealTimers ​

  • Tipo: () => Vitest

Quando i timer sono scaduti, puoi chiamare questo metodo per ripristinare i timer mockati alle loro implementazioni originali. Tutti i timer che erano stati programmati in precedenza verranno scartati.

Varie ​

Un insieme di utili funzioni helper fornite da Vitest.

vi.waitFor ​

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

Attende che il callback venga eseguito con successo. Se il callback lancia un errore o restituisce una Promise rifiutata, continuerà ad attendere finché non avrà successo o scadrà il tempo.

Se le opzioni sono impostate su un numero, l'effetto è equivalente a impostare { timeout: options }.

Questo è molto utile quando è necessario attendere il completamento di un'azione asincrona, ad esempio, quando si avvia un server e si deve attendere che si avvii.

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

test('Server avviato con successo', 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 i callback asincroni

ts
// @vitest-environment jsdom

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

test('L\'elemento esiste nel 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 usato vi.useFakeTimers, vi.waitFor chiama automaticamente vi.advanceTimersByTime(interval) in ogni callback di controllo.

vi.waitUntil ​

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

Questo è simile a vi.waitFor, ma se il callback lancia errori, l'esecuzione viene immediatamente interrotta e viene ricevuto un messaggio di errore. Se il callback restituisce un valore falsy, il controllo successivo continuerà finché non verrà restituito un valore truthy. Questo è utile quando è necessario attendere che qualcosa esista prima di fare il passo successivo.

Si veda l'esempio seguente. Possiamo usare vi.waitUntil per attendere che l'elemento appaia sulla 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 valore predefinito è 1000
    interval: 20, // il valore predefinito è 50
  });

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

vi.hoisted ​

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

Tutte le istruzioni import statiche nei moduli ES vengono sollevate in cima al file, quindi qualsiasi codice definito prima delle importazioni verrà effettivamente eseguito dopo che le importazioni sono state valutate.

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

Per aggirare questa limitazione, è possibile riscrivere le importazioni statiche in quelle dinamiche 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 usando il metodo vi.hoisted. Sotto il cofano, Vitest convertirà le importazioni statiche in quelle dinamiche con live-binding preservati.

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

LE IMPORTAZIONI NON SONO DISPONIBILI

L'esecuzione del codice prima delle importazioni significa che non è possibile accedere alle variabili importate perché non sono ancora definite:

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

vi.hoisted(() => { value }); // lancia un errore

Questo codice produrrà un errore:

Impossibile accedere a '__vi_import_0__' prima dell'inizializzazione

Se è necessario accedere a una variabile da un altro modulo all'interno di vi.hoisted, usare l'importazione dinamica:

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

Tuttavia, è sconsigliato importare qualsiasi cosa all'interno di vi.hoisted perché le importazioni sono già sollevate (hoisted) - se è necessario eseguire qualcosa prima che i test siano in esecuzione, eseguirlo nel modulo importato stesso.

Questo metodo restituisce il valore che è stato restituito dalla factory. Puoi usare quel valore nelle tue factory vi.mock se hai bisogno di un facile accesso a 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);

Si noti che questo metodo può anche essere chiamato in modo asincrono anche se il proprio ambiente non supporta l'await di primo livello:

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

vi.setConfig ​

  • Tipo: RuntimeConfig

Aggiorna la configurazione per il file di test corrente. Questo metodo supporta solo le opzioni di configurazione che influenzeranno il 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 ripristinerà la configurazione allo stato originale.

Pager
Pagina precedenteFunzioni Mock
Pagina successivaexpect

Rilasciato sotto la licenza MIT.

Copyright (c) 2021-Present Vitest Team

https://vitest.dev/api/vi

Rilasciato sotto la licenza MIT.

Copyright (c) 2021-Present Vitest Team