Skip to content
Vitest 3
Main Navigation Guide & APIConfigurationMode NavigateurAPI avancée
3.2.0
2.1.9
1.6.1
0.34.6

Français

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

Français

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

Apparence

Sidebar Navigation

Introduction

Pourquoi Vitest

Démarrage

Fonctionnalités

Configuration de Vitest

API

Référence de l'API des Tests

Fonctions Mocks

vi

expect

expectTypeOf

assert

assertType

Guide

Interface en ligne de commande (CLI)

Filtrage des tests

Projets de Test

Rapporteurs

Couverture de code

Instantanés

Simulation

Parallélisme

Tests de type

Interface utilisateur de Vitest

Tests in-source

Contexte de test

Annotations de test

Environnement de Test

Étendre les Matchers

Intégrations IDE

Débogage

Erreurs courantes

Guide de migration

Migration vers Vitest 3.0

Migration depuis Jest

Performance

Analyse des performances des tests

Amélioration des performances

Mode Navigateur

API avancée

Comparaison avec d'autres exécuteurs de tests

Sur cette page

vi ​

Vitest met à votre disposition des fonctions utilitaires via son module vi. Vous pouvez y accéder globalement (si la configuration globale est activée) ou l'importer directement depuis vitest :

js
import { vi } from 'vitest';

Mocking de modules ​

Cette section décrit l'API à utiliser pour le mocking de modules. Notez que Vitest ne prend pas en charge le mocking des modules importés avec require().

vi.mock ​

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

Substitue tous les modules importés depuis le path fourni par un autre module. Vous pouvez utiliser les alias Vite configurés dans un chemin. L'appel à vi.mock est hoisté, ce qui signifie qu'il sera toujours exécuté avant toutes les importations, quel que soit l'endroit où vous l'appelez. Si vous avez besoin de référencer des variables en dehors de sa portée, vous pouvez les définir dans vi.hoisted et les référencer dans vi.mock.

WARNING

vi.mock ne fonctionne que pour les modules importés avec le mot-clé import. Il ne fonctionne pas avec require.

Afin de hoister vi.mock, Vitest analyse statiquement vos fichiers. Cela implique que vi ne peut pas être utilisé s'il n'est pas directement importé du package vitest (par exemple, depuis un fichier utilitaire). Utilisez vi.mock avec vi importé de vitest, ou activez l'option de configuration globals.

Vitest ne mockera pas les modules importés dans un fichier de setup car ils sont mis en cache au moment de l'exécution d'un fichier de test. Vous pouvez appeler vi.resetModules() dans vi.hoisted pour effacer tous les caches de modules avant d'exécuter un fichier de test.

Si la fonction factory est définie, toutes les importations renverront son résultat. Vitest n'appelle la factory qu'une seule fois et met en cache les résultats pour toutes les importations ultérieures jusqu'à ce que vi.unmock ou vi.doUnmock soit appelé.

Contrairement à jest, la factory peut être asynchrone. Vous pouvez utiliser vi.importActual ou un utilitaire avec la factory passée en premier argument, et obtenir le module original à l'intérieur.

Vous pouvez également fournir un objet avec une propriété spy au lieu d'une fonction factory. Si spy est true, Vitest mockera automatiquement le module comme d'habitude, mais il ne remplacera pas l'implémentation des exportations. Ceci est utile si vous voulez simplement affirmer que la méthode exportée a été appelée correctement par une autre méthode.

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

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

// appelle l'implémentation originale,
// mais permet d'affirmer le comportement plus tard
const result = calculator(1, 2);

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

Vitest prend également en charge une promesse de module au lieu d'une chaîne dans les méthodes vi.mock et vi.doMock pour un meilleur support IDE. Lorsque le fichier est déplacé, le chemin sera mis à jour, et importOriginal hérite automatiquement du type. L'utilisation de cette signature forcera également le type de retour de la factory à être compatible avec le module original (tout en permettant que les exportations soient facultatives).

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(); // le type est inféré
  //    ^?
  return {
    ...mod,
    // remplacer certaines exportations
    total: vi.fn(),
  };
});

En interne, Vitest opère toujours sur une chaîne et non sur un objet module.

Si vous utilisez TypeScript avec des alias paths configurés dans tsconfig.json, le compilateur ne pourra cependant pas résoudre correctement les types d'importation. Pour que cela fonctionne, assurez-vous de remplacer toutes les importations aliasées par leurs chemins relatifs correspondants. Par exemple, utilisez import('./path/to/module.js') au lieu de import('@/module').

WARNING

vi.mock est hoisté (en d'autres termes, déplacé) en haut du fichier. Cela signifie que, peu importe où vous l'écrivez (que ce soit dans beforeEach ou test), il sera en fait appelé avant l'exécution de ce bloc.

Cela signifie également que vous ne pouvez pas utiliser de variables à l'intérieur de la factory qui sont définies en dehors de la factory.

Si vous avez besoin d'utiliser des variables à l'intérieur de la factory, essayez vi.doMock. Il fonctionne de la même manière mais n'est pas hoisté. Notez qu'il ne mocke que les importations ultérieures.

Vous pouvez également référencer des variables définies par la méthode vi.hoisted si elle a été déclarée avant 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

Si vous mockez un module avec une exportation par défaut, vous devrez fournir une clé default dans l'objet de la fonction factory retournée. C'est une particularité des modules ES ; par conséquent, la documentation jest peut différer car jest utilise des modules CommonJS. Par exemple,

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

S'il y a un dossier __mocks__ à côté d'un fichier que vous mockez, et que la factory n'est pas fournie, Vitest essaiera de trouver un fichier du même nom dans le sous-dossier __mocks__ et l'utilisera comme module réel. Si vous mockez une dépendance, Vitest essaiera de trouver un dossier __mocks__ à la racine du projet (par défaut, process.cwd()). Vous pouvez indiquer à Vitest où se trouvent les dépendances via l'option de configuration deps.moduleDirectories.

Par exemple, vous avez cette structure de fichiers :

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

Si vous appelez vi.mock dans un fichier de test sans factory ni options fournies, il trouvera un fichier dans le dossier __mocks__ à utiliser comme module :

ts
import { vi } from 'vitest';

// axios est une exportation par défaut de `__mocks__/axios.js`
import axios from 'axios';

// increment est une exportation nommée de `src/__mocks__/increment.js`
import { increment } from '../increment.js';

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

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

WARNING

Notez que si vous n'appelez pas vi.mock, les modules ne sont pas mockés automatiquement. Pour reproduire le comportement de mocking automatique de Jest, vous pouvez appeler vi.mock pour chaque module requis dans setupFiles.

S'il n'y a pas de dossier __mocks__ ou de factory fournie, Vitest importera le module original et mockera automatiquement toutes ses exportations. Pour les règles appliquées, voir algorithme.

vi.doMock ​

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

Identique à vi.mock, mais il n'est pas hoisté en haut du fichier, ce qui vous permet de référencer des variables dans la portée globale du fichier. La prochaine importation dynamique du module sera mockée.

WARNING

Cela ne mockera pas les modules qui ont été importés avant cet appel. N'oubliez pas que toutes les importations statiques dans ESM sont toujours hoistées, donc placer ceci avant une importation statique ne la forcera pas à être appelée avant l'importation :

ts
vi.doMock('./increment.js'); // ceci sera appelé _après_ l'instruction d'importation

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

// le module n'est pas mocké, car vi.doMock n'est pas encore appelé
increment(1) === 2;

let mockedIncrement = 100;

beforeEach(() => {
  // vous pouvez accéder aux variables à l'intérieur d'une factory
  vi.doMock('./increment.js', () => ({ increment: () => ++mockedIncrement }));
});

test('l\'importation du module suivant importe le module mocké', async () => {
  // l'importation originale n'a pas été mockée, car vi.doMock est évalué après les importations
  expect(increment(1)).toBe(2);
  const { increment: mockedIncrement } = await import('./increment.js');
  // la nouvelle importation dynamique renvoie le module mocké
  expect(mockedIncrement(1)).toBe(101);
  expect(mockedIncrement(1)).toBe(102);
  expect(mockedIncrement(1)).toBe(103);
});

vi.mocked ​

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

Utilitaire de typage pour TypeScript. Renvoie l'objet qui a été passé.

Lorsque partial est true, il attendra un Partial<T> comme valeur de retour. Par défaut, cela indique seulement à TypeScript que les valeurs de premier niveau sont mockées. Vous pouvez passer { deep: true } comme deuxième argument pour indiquer à TypeScript que l'objet entier est mocké, si c'est le cas.

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 est égal à 10', async () => {
  vi.mocked(example.add).mockReturnValue(10);
  expect(example.add(1, 1)).toBe(10);
});

test('valeur de retour mockée avec un typage seulement partiellement correct', 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 }) // ceci est une erreur de type
});

vi.importActual ​

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

Importe un module, en contournant toutes les vérifications pour savoir s'il doit être mocké. Peut être utile si vous souhaitez mocker un module partiellement.

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

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

vi.importMock ​

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

Importe un module avec toutes ses propriétés (y compris les propriétés imbriquées) mockées. Suit les mêmes règles que vi.mock. Pour les règles appliquées, voir algorithme.

vi.unmock ​

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

Supprime le module du registre des mocks. Tous les appels à l'importation renverront le module original même s'il avait été mocké auparavant. Cet appel est hoisté en haut du fichier, il ne démockera donc que les modules définis dans setupFiles, par exemple.

vi.doUnmock ​

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

Identique à vi.unmock, mais il n'est pas hoisté en haut du fichier. La prochaine importation du module importera le module original au lieu du mock. Cela n'annulera pas la simulation des modules précédemment importés.

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

// increment est déjà mocké, car vi.mock est hoisté
increment(1) === 100;

// ceci est hoisté, et la factory est appelée avant l'importation à la ligne 1
vi.mock('./increment.js', () => ({ increment: () => 100 }));

// tous les appels sont mockés, et `increment` renvoie toujours 100
increment(1) === 100;
increment(30) === 100;

// ceci n'est pas hoisté, donc une autre importation renverra un module non mocké
vi.doUnmock('./increment.js');

// ceci renvoie TOUJOURS 100, car `vi.doUnmock` ne réévalue pas un module
increment(1) === 100;
increment(30) === 100;

// la prochaine importation n'est pas mockée, maintenant `increment` est la fonction originale qui renvoie count + 1
const { increment: unmockedIncrement } = await import('./increment.js');

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

vi.resetModules ​

  • Type : () => Vitest

Réinitialise le registre des modules en effaçant le cache de tous les modules. Cela permet aux modules d'être réévalués lors d'une nouvelle importation. Les importations de niveau supérieur ne peuvent pas être réévaluées. Peut être utile pour isoler les modules dont l'état local entre en conflit entre les tests.

ts
import { vi } from 'vitest';

import { data } from './data.js'; // Ne sera pas réévalué avant chaque test

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

test('changer l\'état', async () => {
  const mod = await import('./some/path.js'); // Sera réévalué
  mod.changeLocalState('nouvelle valeur');
  expect(mod.getLocalState()).toBe('nouvelle valeur');
});

test('le module a l\'ancien état', async () => {
  const mod = await import('./some/path.js'); // Sera réévalué
  expect(mod.getLocalState()).toBe('ancienne valeur');
});

WARNING

Ne réinitialise pas le registre des mocks. Pour effacer le registre des mocks, utilisez vi.unmock ou vi.doUnmock.

vi.dynamicImportSettled ​

Attend que toutes les importations dynamiques soient résolues. Utile si vous avez un appel synchrone qui déclenche l'importation d'un module que vous ne pouvez pas attendre par d'autres moyens.

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

// impossible de suivre l'importation car la Promesse n'est pas retournée
function renderComponent() {
  import('./component.js').then(({ render }) => {
    render();
  });
}

test('les opérations sont résolues', async () => {
  renderComponent();
  await vi.dynamicImportSettled();
  expect(document.querySelector('.component')).not.toBeNull();
});

TIP

Si, lors d'une importation dynamique, une autre importation dynamique est déclenchée, cette méthode attendra que toutes soient résolues.

Cette méthode attendra également le prochain tick de setTimeout après la résolution de l'importation, afin que toutes les opérations synchrones soient terminées.

Mocking de fonctions et d'objets ​

Cette section décrit comment travailler avec les mocks de méthodes et remplacer les variables d'environnement et globales.

vi.fn ​

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

Crée un espion sur une fonction, bien qu'il puisse être créé sans en fournir une. Chaque fois qu'une fonction est invoquée, elle stocke ses arguments d'appel, ses valeurs de retour et ses instances. De plus, vous pouvez manipuler son comportement avec des méthodes. Si aucune fonction n'est donnée, le mock renverra undefined lorsqu'il sera invoqué.

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

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

Mocke en profondeur les propriétés et les méthodes d'un objet donné de la même manière que vi.mock() mocke les exportations de modules. Voir automocking pour plus de détails.

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 ​

  • Type : (fn: Function) => boolean

Vérifie qu'un paramètre donné est une fonction mockée. Si vous utilisez TypeScript, cela affinera également son type.

vi.clearAllMocks ​

Appelle .mockClear() sur tous les espions. Cela effacera l'historique des mocks sans affecter leurs implémentations.

vi.resetAllMocks ​

Appelle .mockReset() sur tous les espions. Cela effacera l'historique des mocks et réinitialisera l'implémentation de chaque mock à son état original.

vi.restoreAllMocks ​

Appelle .mockRestore() sur tous les espions. Cela effacera l'historique des mocks, restaurera toutes les implémentations de mock originales et restaurera les descripteurs originaux des objets espionnés.

vi.spyOn ​

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

Crée un espion sur une méthode ou un getter/setter d'un objet à l'instar de vi.fn(). Il renvoie une fonction mockée.

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

Dans les environnements qui prennent en charge la gestion explicite des ressources, vous pouvez utiliser using au lieu de const pour appeler automatiquement mockRestore sur toute fonction mockée lorsque le bloc englobant est quitté. C'est particulièrement utile pour les méthodes espionnées :

ts
it('appelle console.log', () => {
  using spy = vi.spyOn(console, 'log').mockImplementation(() => {})
  debug('message')
  expect(spy).toHaveBeenCalled()
})
// console.log est restauré ici

TIP

Vous pouvez appeler vi.restoreAllMocks dans afterEach (ou activer test.restoreMocks) pour restaurer toutes les méthodes à leurs implémentations originales. Cela restaurera le descripteur d'objet original, empêchant ainsi de modifier l'implémentation de la méthode :

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

TIP

Il n'est pas possible d'espionner les méthodes exportées dans le mode navigateur. Au lieu de cela, vous pouvez espionner chaque méthode exportée en appelant vi.mock("./file-path.js", { spy: true }). Cela mockera chaque exportation mais maintiendra son implémentation intacte, vous permettant d'affirmer si la méthode a été appelée correctement.

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

Et bien qu'il soit possible d'espionner les exportations dans jsdom ou d'autres environnements Node.js, cela pourrait changer à l'avenir.

vi.stubEnv ​

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

Modifie la valeur de la variable d'environnement dans process.env et import.meta.env. Vous pouvez restaurer sa valeur via l'appel à vi.unstubAllEnvs.

ts
import { vi } from 'vitest';

// `process.env.NODE_ENV` et `import.meta.env.NODE_ENV`
// sont "development" avant d'appeler "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;

// ne change pas les autres envs
import.meta.env.MODE === 'development';

TIP

Vous pouvez également modifier la valeur en l'affectant directement, mais vous ne pourrez pas utiliser vi.unstubAllEnvs pour restaurer la valeur précédente :

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

vi.unstubAllEnvs ​

  • Type : () => Vitest

Restaure toutes les valeurs import.meta.env et process.env qui ont été modifiées avec vi.stubEnv. Lorsqu'elle est appelée pour la première fois, Vitest mémorise la valeur originale et la conservera jusqu'à ce que unstubAllEnvs soit appelée à nouveau.

ts
import { vi } from 'vitest';

// `process.env.NODE_ENV` et `import.meta.env.NODE_ENV`
// sont "development" avant d'appeler 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();

// restaure la valeur stockée avant le premier appel à "stubEnv"
process.env.NODE_ENV === 'development';
import.meta.env.NODE_ENV === 'development';

vi.stubGlobal ​

  • Type : (name: string | number | symbol, value: unknown) => Vitest

Permet de modifier la valeur d'une variable globale. Vous pouvez restaurer sa valeur originale via l'appel à vi.unstubAllGlobals.

ts
import { vi } from 'vitest';

// `innerWidth` est "0" avant d'appeler stubGlobal

vi.stubGlobal('innerWidth', 100);

innerWidth === 100;
globalThis.innerWidth === 100;
// si vous utilisez jsdom ou happy-dom
window.innerWidth === 100;

TIP

Vous pouvez également modifier la valeur en l'affectant directement à globalThis ou window (si vous utilisez l'environnement jsdom ou happy-dom), mais vous ne pourrez pas utiliser vi.unstubAllGlobals pour restaurer la valeur originale :

ts
globalThis.innerWidth = 100;
// si vous utilisez jsdom ou happy-dom
window.innerWidth = 100;

vi.unstubAllGlobals ​

  • Type : () => Vitest

Restaure toutes les valeurs globales sur globalThis/global (et window/top/self/parent, si vous utilisez l'environnement jsdom ou happy-dom) qui ont été modifiées avec vi.stubGlobal. Lorsqu'elle est appelée pour la première fois, Vitest mémorise la valeur originale et la conservera jusqu'à ce que unstubAllGlobals soit appelée à nouveau.

ts
import { vi } from 'vitest';

const Mock = vi.fn();

// IntersectionObserver est "undefined" avant d'appeler "stubGlobal"

vi.stubGlobal('IntersectionObserver', Mock);

IntersectionObserver === Mock;
global.IntersectionObserver === Mock;
globalThis.IntersectionObserver === Mock;
// si vous utilisez jsdom ou happy-dom
window.IntersectionObserver === Mock;

vi.unstubAllGlobals();

globalThis.IntersectionObserver === undefined;
'IntersectionObserver' in globalThis === false;
// lève une ReferenceError, car elle n'est plus définie
IntersectionObserver === undefined;

Fake Timers ​

Cette section décrit comment travailler avec les fake timers.

vi.advanceTimersByTime ​

  • Type : (ms: number) => Vitest

Cette méthode invoquera chaque minuteur initié jusqu'à ce que le nombre de millisecondes spécifié soit écoulé ou que la file d'attente soit vide, selon la première de ces conditions.

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

vi.advanceTimersByTime(150);

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

vi.advanceTimersByTimeAsync ​

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

Cette méthode invoquera chaque minuteur initié jusqu'à ce que le nombre de millisecondes spécifié soit écoulé ou que la file d'attente soit vide, selon la première de ces conditions. Cela inclura les minuteurs définis de manière asynchrone.

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

await vi.advanceTimersByTimeAsync(150);

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

vi.advanceTimersToNextTimer ​

  • Type : () => Vitest

Exécutera le prochain minuteur disponible. Utile pour effectuer des assertions entre chaque appel de minuteur. Vous pouvez l'appeler en chaînant les appels pour gérer les minuteurs vous-même.

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

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

vi.advanceTimersToNextTimerAsync ​

  • Type : () => Promise<Vitest>

Exécutera le prochain minuteur disponible et attendra qu'il soit résolu s'il a été défini de manière asynchrone. Utile pour effectuer des assertions entre chaque appel de minuteur.

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

  • Type : () => Vitest

Similaire à vi.advanceTimersByTime, mais avancera les minuteurs du nombre de millisecondes nécessaires pour exécuter les rappels actuellement planifiés avec requestAnimationFrame.

ts
let frameRendered = false;

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

vi.advanceTimersToNextFrame();

expect(frameRendered).toBe(true);

vi.getTimerCount ​

  • Type : () => number

Renvoie le nombre de minuteurs en attente.

vi.clearAllTimers ​

Supprime tous les minuteurs qui sont planifiés pour s'exécuter. Ces minuteurs ne seront jamais exécutés.

vi.getMockedSystemTime ​

  • Type : () => Date | null

Renvoie la date actuelle mockée. Si la date n'est pas mockée, la méthode renverra null.

vi.getRealSystemTime ​

  • Type : () => number

Lorsque vous utilisez vi.useFakeTimers, les appels Date.now sont mockés. Si vous avez besoin d'obtenir l'heure réelle en millisecondes, vous pouvez appeler cette fonction.

vi.runAllTicks ​

  • Type : () => Vitest

Appelle chaque microtâche qui a été mise en attente par process.nextTick. Cela exécutera également toutes les microtâches qui se sont planifiées elles-mêmes.

vi.runAllTimers ​

  • Type : () => Vitest

Cette méthode invoquera chaque minuteur initié jusqu'à ce que la file d'attente des timers soit vide. Cela signifie que chaque minuteur appelé pendant runAllTimers sera exécuté. Si vous avez un intervalle infini, une exception sera levée après 10 000 tentatives (peut être configuré avec 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 ​

  • Type : () => Promise<Vitest>

Cette méthode invoquera de manière asynchrone chaque minuteur initié jusqu'à ce que la file d'attente des timers soit vide. Cela signifie que chaque minuteur appelé pendant runAllTimersAsync sera exécuté, même les minuteurs asynchrones. Si vous avez un intervalle infini, une exception sera levée après 10 000 tentatives (peut être configuré avec fakeTimers.loopLimit).

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

await vi.runAllTimersAsync();

// log: result

vi.runOnlyPendingTimers ​

  • Type : () => Vitest

Cette méthode exécutera chaque minuteur qui a été planifié après l'appel de vi.useFakeTimers. Elle ne déclenchera aucun minuteur qui a été planifié durant son exécution.

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

vi.runOnlyPendingTimers();

// log: 1

vi.runOnlyPendingTimersAsync ​

  • Type : () => Promise<Vitest>

Cette méthode appellera de manière asynchrone chaque minuteur qui a été planifié après l'appel de vi.useFakeTimers, même les asynchrones. Elle ne déclenchera aucun minuteur qui a été planifié durant son exécution.

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 ​

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

Si les fake timers sont activés, cette méthode simule un utilisateur modifiant l'horloge système (ce qui affectera les API liées à la date comme hrtime, performance.now ou new Date()). Cependant, elle ne déclenchera aucun minuteur. Si les fake timers ne sont pas activés, cette méthode ne mockera que les appels Date.*.

Utile si vous avez besoin de tester quelque chose qui dépend de la date actuelle, par exemple les appels Luxon dans votre code.

Accepte les mêmes arguments de type chaîne et nombre que le constructeur Date.

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

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

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

vi.useRealTimers();

vi.useFakeTimers ​

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

Pour activer le mocking des timers, vous devez appeler cette méthode. Elle interceptera tous les appels ultérieurs aux minuteurs (tels que setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, clearImmediate et Date) jusqu'à ce que vi.useRealTimers() soit appelé.

Le mocking de nextTick n'est pas pris en charge lors de l'exécution de Vitest dans node:child_process en utilisant --pool=forks. NodeJS utilise process.nextTick en interne dans node:child_process et se bloque lorsqu'il est mocké. Le mocking de nextTick est pris en charge lors de l'exécution de Vitest avec --pool=threads.

L'implémentation est basée en interne sur @sinonjs/fake-timers.

TIP

vi.useFakeTimers() ne mocke pas automatiquement process.nextTick et queueMicrotask. Mais vous pouvez l'activer en spécifiant l'option toFake : vi.useFakeTimers({ toFake: ['nextTick', 'queueMicrotask'] }).

vi.isFakeTimers ​

  • Type : () => boolean

Renvoie true si les fake timers sont activés.

vi.useRealTimers ​

  • Type : () => Vitest

Lorsque les timers ont terminé leur exécution, vous pouvez appeler cette méthode pour restaurer les mocks de timers à leurs implémentations originales. Tous les minuteurs qui étaient programmés auparavant seront annulés.

Divers ​

Un ensemble de fonctions utilitaires fournies par Vitest.

vi.waitFor ​

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

Attend que le rappel soit exécuté avec succès. Si le rappel lève une erreur ou renvoie une promesse rejetée, l'attente se poursuivra jusqu'à ce qu'il réussisse ou expire.

Si les options sont définies sur un nombre, l'effet est équivalent à { timeout: options }.

C'est très utile lorsque vous devez attendre qu'une action asynchrone se termine, par exemple, lorsque vous démarrez un serveur et que vous devez attendre qu'il démarre.

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

test('Le serveur a démarré avec succès', async () => {
  const server = createServer();

  await vi.waitFor(
    () => {
      if (!server.isReady) {
        throw new Error('Le serveur n\'a pas démarré');
      }

      console.log('Serveur démarré');
    },
    {
      timeout: 500, // la valeur par défaut est 1000
      interval: 20, // la valeur par défaut est 50
    }
  );
  expect(server.isReady).toBe(true);
});

Cela fonctionne également pour les rappels asynchrones

ts
// @vitest-environment jsdom

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

test('L\'élément existe dans un DOM', async () => {
  // commencer à peupler le DOM
  populateDOMAsync();

  const element = await vi.waitFor(
    async () => {
      // essayer d'obtenir l'élément jusqu'à ce qu'il existe
      const element = (await getDOMElementAsync()) as HTMLElement | null;
      expect(element).toBeTruthy();
      expect(element.dataset.initialized).toBeTruthy();
      return element;
    },
    {
      timeout: 500, // la valeur par défaut est 1000
      interval: 20, // la valeur par défaut est 50
    }
  );
  expect(element).toBeInstanceOf(HTMLElement);
});

Si vi.useFakeTimers est utilisé, vi.waitFor appelle automatiquement vi.advanceTimersByTime(interval) à chaque vérification.

vi.waitUntil ​

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

Ceci est similaire à vi.waitFor, mais si le rappel lève des erreurs, l'exécution est immédiatement interrompue et une erreur est renvoyée. Si le rappel renvoie une valeur falsy, la prochaine vérification continuera jusqu'à ce qu'une valeur truthy soit renvoyée. C'est utile lorsque vous devez attendre que quelque chose existe avant de passer à l'étape suivante.

Regardez l'exemple ci-dessous. Nous pouvons utiliser vi.waitUntil pour attendre que l'élément apparaisse sur la page, puis nous pouvons faire quelque chose avec l'élément.

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

test('Le rendu de l\'élément est correct', async () => {
  const element = await vi.waitUntil(() => document.querySelector('.element'), {
    timeout: 500, // la valeur par défaut est 1000
    interval: 20, // la valeur par défaut est 50
  });

  // faire quelque chose avec l'élément
  expect(element.querySelector('.element-child')).toBeTruthy();
});

vi.hoisted ​

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

Toutes les instructions import statiques dans les modules ES sont hoistées en haut du fichier, de sorte que tout code défini avant les importations sera exécuté après l'évaluation des importations.

Cependant, il peut être utile d'invoquer certains effets secondaires comme le mocking de dates avant d'importer un module.

Pour contourner cette limitation, vous pouvez réécrire les importations statiques en importations dynamiques comme ceci :

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

Lors de l'exécution de vitest, vous pouvez le faire automatiquement avec la méthode vi.hoisted. En interne, Vitest convertira les importations statiques en importations dynamiques avec des live-bindings préservés.

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

LES IMPORTATIONS NE SONT PAS DISPONIBLES

Exécuter du code avant les importations signifie que vous ne pouvez pas accéder aux variables importées car elles ne sont pas encore définies :

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

vi.hoisted(() => { value }); // lève une erreur

Ce code produira une erreur :

Impossible d'accéder à '__vi_import_0__' avant l'initialisation

Si vous avez besoin d'accéder à une variable d'un autre module à l'intérieur de vi.hoisted, utilisez l'importation dynamique :

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

Cependant, il est déconseillé d'importer quoi que ce soit à l'intérieur de vi.hoisted car les importations sont déjà hoistées - si vous avez besoin d'exécuter quelque chose avant l'exécution des tests, faites-le simplement dans le module importé lui-même.

Cette méthode renvoie la valeur qui a été renvoyée par la factory. Vous pouvez utiliser cette valeur dans vos factories vi.mock si vous avez besoin d'un accès facile aux variables définies localement :

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

Notez que cette méthode peut également être appelée de manière asynchrone même si votre environnement ne prend pas en charge l'await de niveau supérieur :

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

vi.setConfig ​

  • Type : RuntimeConfig

Met à jour la configuration du fichier de test actuel. Cette méthode ne prend en charge que les options de configuration qui s'appliqueront au fichier de test actuel :

ts
vi.setConfig({
  allowOnly: true,
  testTimeout: 10_000,
  hookTimeout: 10_000,
  clearMocks: true,
  restoreMocks: true,
  fakeTimers: {
    now: new Date(2021, 11, 19),
    // prend en charge l'objet entier
  },
  maxConcurrency: 10,
  sequence: {
    hooks: 'stack',
    // ne prend en charge que "sequence.hooks"
  },
});

vi.resetConfig ​

  • Type : RuntimeConfig

Si vi.setConfig a été appelé précédemment, cela réinitialisera la configuration à son état original.

Pager
Page précédenteFonctions Mocks
Page suivanteexpect

Publié sous la licence MIT.

Copyright (c) 2021-Present Vitest Team

https://vitest.dev/api/vi

Publié sous la licence MIT.

Copyright (c) 2021-Present Vitest Team