Skip to content
Vitest 1
Main Navigation GuideAPIConfigurationAvancé
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

Guide

Pourquoi Vitest

Premiers pas

Fonctionnalités

Espace de travail

Interface de ligne de commande

Filtrage des tests

Reporters

Couverture

Instantané (Snapshot)

Simulations

Tests de Type

Interface utilisateur de Vitest

Mode Navigateur

Tests intégrés au code source

Contexte de Test

Environnement de test

Extension des vérificateurs (Matchers)

Intégrations pour IDE

Débogage

Comparaison avec d'autres outils de test

Guide de migration

Erreurs courantes

Améliorer les performances

API

Référence de l'API de Test

Fonctions Mock

Vi

expect

expectTypeOf

assert

assertType

Configuration

Configuration du fichier Vitest

Configuration de Vitest

Sur cette page

Vi ​

Vitest fournit des fonctions utilitaires pour vous aider avec son assistant vi. Vous pouvez y accéder globalement (lorsque la configuration des globales est activée), ou l'importer directement depuis vitest :

js
import { vi } from 'vitest';

Modules Mockés ​

Cette section décrit l'API que vous pouvez utiliser lors du mocking d'un module. Sachez que Vitest ne prend pas en charge le mocking des modules importés via require().

vi.mock ​

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

Remplace tous les modules importés à partir du chemin fourni par un autre module. Vous pouvez utiliser les alias Vite configurés à l'intérieur d'un chemin. L'appel à vi.mock est remonté (hoisted), peu importe où vous l'appelez. Il sera toujours exécuté avant toutes les importations. Si vous devez référencer des variables en dehors de sa portée, vous pouvez les définir à l'intérieur de vi.hoisted et les référencer dans vi.mock.

WARNING

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

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

Vitest ne moquera pas les modules qui ont été importés à l'intérieur d'un fichier de configuration car ils sont mis en cache au moment où un fichier de test est en cours d'exécution. Vous pouvez appeler vi.resetModules() à l'intérieur de vi.hoisted pour effacer tous les caches de modules avant d'exécuter un fichier de test.

WARNING

Le mode navigateur ne prend pas actuellement en charge le mocking des modules. Vous pouvez suivre l'avancement de cette fonctionnalité dans l'issue GitHub.

Si factory est défini, toutes les importations retourneront son résultat. Vitest appelle factory une seule fois et met en cache les résultats pour toutes les importations suivantes jusqu'à ce que vi.unmock ou vi.doUnmock soit appelé.

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

js
import { vi } from 'vitest';
// ---cut---
// when using JavaScript

vi.mock('./path/to/module.js', async importOriginal => {
  const mod = await importOriginal();
  return {
    ...mod,
    // remplacer certaines exportations
    namedExport: vi.fn(),
  };
});
ts
// when using TypeScript

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

WARNING

vi.mock est remonté (hoisted), c'est-à-dire déplacé, en haut du fichier. Cela signifie que chaque fois que vous l'écrivez (que ce soit à l'intérieur de beforeEach ou test), il sera en fait appelé avant cela.

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 devez utiliser des variables à l'intérieur de la factory, essayez vi.doMock. Il fonctionne de la même manière, mais n'est pas remonté (hoisted). Sachez qu'il ne moque que les importations suivantes.

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 moquez un module avec une exportation par défaut, vous devrez fournir une clé default dans l'objet retourné par la fonction factory. Il s'agit d'une mise en garde spécifique aux modules ES ; par conséquent, la documentation de 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 existe un dossier __mocks__ à côté d'un fichier que vous moquez, et que la factory n'est pas fournie, Vitest essaiera de trouver un fichier portant le même nom dans le sous-dossier __mocks__ et l'utilisera comme module réel. Si vous moquez une dépendance, Vitest essaiera de trouver un dossier __mocks__ dans la racine du projet (la valeur par défaut est 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 fournie, Vitest trouvera un fichier dans le dossier __mocks__ à utiliser comme module :

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

// axios is a default export from `__mocks__/axios.js`
import axios from 'axios';

// increment is a named export from `src/__mocks__/increment.js`
import { increment } from '../increment.js';

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

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

WARNING

Sachez que si vous n'appelez pas vi.mock, les modules ne sont pas mockés automatiquement. Pour reproduire le comportement d'automocking de Jest, vous pouvez appeler vi.mock pour chaque module requis à l'intérieur de setupFiles.

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

vi.doMock ​

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

Identique à vi.mock, mais il n'est pas remonté (hoisted) en haut du fichier, vous pouvez donc référencer des variables dans la portée globale du fichier. La prochaine importation dynamique du module sera mockée.

WARNING

Cela ne moquera pas les modules qui ont été importés avant son appel. N'oubliez pas que toutes les importations statiques dans ESM sont toujours remontées (hoisted). Par conséquent, placer ceci avant l'importation statique ne forcera pas son appel avant l'importation :

ts
vi.doMock('./increment.js'); // this will be called _after_ the import statement

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

// the module is not mocked, because vi.doMock is not called yet
increment(1) === 2;

let mockedIncrement = 100;

beforeEach(() => {
  // you can access variables inside a factory
  vi.doMock('./increment.js', () => ({ increment: () => ++mockedIncrement }));
});

test('importing the next module imports mocked one', async () => {
  // original import WAS NOT MOCKED, because vi.doMock is evaluated AFTER imports
  expect(increment(1)).toBe(2);
  const { increment: mockedIncrement } = await import('./increment.js');
  // new dynamic import returns mocked module
  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>

Assistant de type pour TypeScript. Retourne simplement l'objet qui a été passé.

Lorsque partial est true, il s'attendra à un Partial<T> comme valeur de retour. Par défaut, cela fera seulement croire à 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é en profondeur, si c'est effectivement le cas.

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 ​

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

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

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

  return { ...axios, 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) => void

Supprime le module du registre mocké. Tous les appels à import retourneront le module original même s'il a été mocké auparavant. Cet appel est remonté (hoisted) en haut du fichier et ne démoquera donc que les modules qui ont été définis dans setupFiles, par exemple.

vi.doUnmock ​

  • Type: (path: string) => void

Identique à vi.unmock, mais n'est pas remonté (hoisted) en haut du fichier. La prochaine importation du module importera le module original au lieu du mock. Cela ne démoquera pas les modules importés précédemment.

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

// increment is already mocked, because vi.mock is hoisted
increment(1) === 100;

// this is hoisted, and factory is called before the import on line 1
vi.mock('./increment.js', () => ({ increment: () => 100 }));

// all calls are mocked, and `increment` always returns 100
increment(1) === 100;
increment(30) === 100;

// this is not hoisted, so other import will return unmocked module
vi.doUnmock('./increment.js');

// this STILL returns 100, because `vi.doUnmock` doesn't reevaluate a module
increment(1) === 100;
increment(30) === 100;

// the next import is unmocked, now `increment` is the original function that returns 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 de la réimportation. Les importations de niveau supérieur ne peuvent pas être réévaluées. Cela peut être utile pour isoler les modules où l'état local entre en conflit entre les tests.

ts
import { vi } from 'vitest';

import { data } from './data.js'; // Will not get reevaluated beforeEach test

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

test('change state', async () => {
  const mod = await import('./some/path.js'); // Will get reevaluated
  mod.changeLocalState('new value');
  expect(mod.getLocalState()).toBe('new value');
});

test('module has old state', async () => {
  const mod = await import('./some/path.js'); // Will get reevaluated
  expect(mod.getLocalState()).toBe('old value');
});

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 chargées. Utile si vous avez un appel synchrone qui commence à importer un module que vous ne pouvez pas attendre autrement.

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

// cannot track import because Promise is not returned
function renderComponent() {
  import('./component.js').then(({ render }) => {
    render();
  });
}

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

TIP

Si, pendant une importation dynamique, une autre importation dynamique est initiée, cette méthode attendra que toutes soient résolues.

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

Mocking des Fonctions et des 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 initialisé sans fonction. Chaque fois qu'une fonction est invoquée, elle stocke ses arguments d'appel, ses retours et ses instances. De plus, vous pouvez manipuler son comportement avec des méthodes. Si aucune fonction n'est donnée, le mock retournera undefined lorsqu'il sera invoqué.

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 ​

  • Type: (fn: Function) => boolean

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

vi.clearAllMocks ​

Appelle .mockClear() sur tous les espions. Cela supprimera l'historique des mocks, mais ne réinitialisera pas leur implémentation à la valeur par défaut.

vi.resetAllMocks ​

Appelle .mockReset() sur tous les espions. Cela supprimera l'historique des mocks et réinitialisera son implémentation à une fonction vide (retournera undefined).

vi.restoreAllMocks ​

Appelle .mockRestore() sur tous les espions. Cela supprimera l'historique des mocks et réinitialisera son implémentation à celle d'origine.

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 accesseur (getter/setter) d'un objet, similaire à vi.fn(). Il retourne une fonction mockée.

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

Vous pouvez appeler vi.restoreAllMocks à l'intérieur de afterEach (ou activer test.restoreMocks) pour restaurer toutes les méthodes à leurs implémentations d'origine. Cela restaurera le descripteur d'objet original, vous ne pourrez donc pas 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()); // still 42!

vi.stubEnv 0.26.0+ ​

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

Modifie la valeur de la variable d'environnement dans process.env et import.meta.env. Vous pouvez restaurer sa valeur en appelant vi.unstubAllEnvs.

ts
import { vi } from 'vitest';

// `process.env.NODE_ENV` and `import.meta.env.NODE_ENV`
// are "development" before calling "vi.stubEnv"

vi.stubEnv('NODE_ENV', 'production');

process.env.NODE_ENV === 'production';
import.meta.env.NODE_ENV === 'production';
// doesn't change other envs
import.meta.env.MODE === 'development';

TIP

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

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

vi.unstubAllEnvs 0.26.0+ ​

  • Type: () => Vitest

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

ts
import { vi } from 'vitest';

// `process.env.NODE_ENV` and `import.meta.env.NODE_ENV`
// are "development" before calling 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();

// restores to the value that were stored before the first "stubEnv" call
process.env.NODE_ENV === 'development';
import.meta.env.NODE_ENV === 'development';

vi.stubGlobal ​

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

Modifie la valeur d'une variable globale. Vous pouvez restaurer sa valeur d'origine en appelant vi.unstubAllGlobals.

ts
import { vi } from 'vitest';

// `innerWidth` is "0" before calling stubGlobal

vi.stubGlobal('innerWidth', 100);

innerWidth === 100;
globalThis.innerWidth === 100;
// if you are using jsdom or happy-dom
window.innerWidth === 100;

TIP

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

ts
globalThis.innerWidth = 100;
// if you are using jsdom or happy-dom
window.innerWidth = 100;

vi.unstubAllGlobals 0.26.0+ ​

  • Type: () => Vitest

Restaure toutes les valeurs globales dans 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'il est appelé pour la première fois, Vitest mémorise la valeur d'origine et la stocke jusqu'à ce que unstubAllGlobals soit appelé à nouveau.

ts
import { vi } from 'vitest';

const Mock = vi.fn();

// IntersectionObserver is "undefined" before calling "stubGlobal"

vi.stubGlobal('IntersectionObserver', Mock);

IntersectionObserver === Mock;
global.IntersectionObserver === Mock;
globalThis.IntersectionObserver === Mock;
// if you are using jsdom or happy-dom
window.IntersectionObserver === Mock;

vi.unstubAllGlobals();

globalThis.IntersectionObserver === undefined;
'IntersectionObserver' in globalThis === false;
// throws ReferenceError, because it's not defined
IntersectionObserver === undefined;

Timers simulés (Fake Timers) ​

Cette section décrit comment travailler avec les faux temporisateurs.

vi.advanceTimersByTime ​

  • Type: (ms: number) => Vitest

Cette méthode avance les timers simulés du nombre de millisecondes spécifié, ou jusqu'à ce que la file d'attente des timers soit vide, selon la première éventualité.

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 ​

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

Cette méthode avance de manière asynchrone les timers simulés du nombre de millisecondes spécifié, ou jusqu'à ce que la file d'attente des timers soit vide, selon la première éventualité. Elle inclut les timers définis de manière asynchrone.

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 ​

  • Type: () => Vitest

Exécute le prochain timer disponible dans la file d'attente. Utile pour vérifier l'état entre chaque exécution de timer. Vous pouvez chaîner les appels pour contrôler l'exécution des timers manuellement.

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 ​

  • Type: () => Promise<Vitest>

Exécute de manière asynchrone le prochain timer disponible et attend sa résolution s'il a été défini de manière asynchrone. Utile pour vérifier l'état entre chaque exécution de 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 ​

  • Type: () => number

Retourne le nombre de timers en attente d'exécution.

vi.clearAllTimers ​

Supprime tous les timers programmés. Ces timers ne seront pas exécutés.

vi.getMockedSystemTime ​

  • Type: () => Date | null

Retourne la date simulée actuelle définie avec setSystemTime. Si la date n'est pas simulée, la méthode retourne null.

vi.getRealSystemTime ​

  • Type: () => number

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

vi.runAllTicks ​

  • Type: () => Vitest

Exécute toutes les microtâches mises en file d'attente par process.nextTick. Cela exécutera également toutes les microtâches planifiées par ces dernières.

vi.runAllTimers ​

  • Type: () => Vitest

Cette méthode exécute tous les timers simulés jusqu'à ce que la file d'attente des timers soit vide. Chaque timer appelé pendant runAllTimers sera déclenché. Si un intervalle infini est présent, une exception sera levée après 10 000 tentatives (configurable avec 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 ​

  • Type: () => Promise<Vitest>

Cette méthode exécute de manière asynchrone tous les timers simulés jusqu'à ce que la file d'attente des timers soit vide. Chaque timer appelé pendant runAllTimersAsync sera déclenché, y compris les timers asynchrones. Si un intervalle infini est présent, une exception sera levée après 10 000 tentatives (configurable avec fakeTimers.loopLimit).

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

await vi.runAllTimersAsync();

// log: result

vi.runOnlyPendingTimers ​

  • Type: () => Vitest

Cette méthode exécute uniquement les timers qui ont été initialisés après l'appel de vi.useFakeTimers. Elle n'exécutera pas les timers initialisés pendant son exécution.

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

vi.runOnlyPendingTimers();

// log: 1

vi.runOnlyPendingTimersAsync ​

  • Type: () => Promise<Vitest>

Cette méthode exécute de manière asynchrone uniquement les timers qui ont été initialisés après l'appel de vi.useFakeTimers, y compris les timers asynchrones. Elle n'exécutera pas les timers initialisés pendant son exécution.

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 ​

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

Si les timers simulés sont activés, cette méthode simule la modification de l'horloge système par un utilisateur (affecte les API liées à la date comme hrtime, performance.now ou new Date()). Cependant, elle ne déclenche aucun timer. Si les faux timers ne sont pas activés, cette méthode ne simulera que les appels à Date.*.

Utile si vous devez tester du code qui dépend de la date actuelle, par exemple, les appels à Luxon dans votre code.

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 ​

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

Pour activer la simulation des timers, il est nécessaire d'appeler cette méthode. Elle intercepte tous les appels ultérieurs aux timers (tels que setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, clearImmediate et Date) jusqu'à ce que vi.useRealTimers() soit appelé.

La simulation de nextTick n'est pas prise en charge lorsque Vitest est exécuté dans node:child_process en utilisant --pool=forks. NodeJS utilise process.nextTick en interne dans node:child_process et se bloque lorsqu'il est simulé. La simulation de nextTick est prise en charge lors de l'exécution de Vitest avec --pool=threads.

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

TIP

Depuis la version 0.35.0, vi.useFakeTimers() ne simule plus automatiquement process.nextTick. Il peut toujours être simulé en spécifiant l'option dans l'argument toFake : vi.useFakeTimers({ toFake: ['nextTick'] }).

vi.isFakeTimers 0.34.5+ ​

  • Type: () => boolean

Retourne true si les faux timers sont activés.

vi.useRealTimers ​

  • Type: () => Vitest

Lorsque les timers simulés ne sont plus nécessaires, vous pouvez appeler cette méthode pour rétablir les timers à leurs implémentations d'origine. Tous les timers qui ont été programmés seront supprimés.

Divers ​

Un ensemble de fonctions d'assistance utiles fournies par Vitest.

vi.waitFor 0.34.5+ ​

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

Attend l'exécution réussie du callback. Si le callback lève une exception ou retourne une promesse rejetée, l'attente continue jusqu'à ce qu'il réussisse ou que le délai d'attente expire.

Particulièrement utile lorsque vous devez attendre la fin d'une action asynchrone, par exemple, lorsque vous démarrez un serveur et que vous devez attendre qu'il soit prêt.

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

test('Server started successfully', async () => {
  const server = createServer();

  await vi.waitFor(
    () => {
      if (!server.isReady) throw new Error('Server not started');

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

Cela fonctionne également pour les callbacks asynchrones

ts
// @vitest-environment jsdom

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

test('Element exists in a DOM', async () => {
  // start populating DOM
  populateDOMAsync();

  const element = await vi.waitFor(
    async () => {
      // try to get the element until it exists
      const element = (await getDOMElementAsync()) as HTMLElement | null;
      expect(element).toBeTruthy();
      expect(element.dataset.initialized).toBeTruthy();
      return element;
    },
    {
      timeout: 500, // la valeur par défaut est de 1000
      interval: 20, // la valeur par défaut est de 50
    }
  );
  expect(element).toBeInstanceOf(HTMLElement);
});

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

vi.waitUntil 0.34.5+ ​

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

Similaire à vi.waitFor, mais si le callback lève une exception, l'exécution est immédiatement interrompue et un message d'erreur est affiché. Si le callback retourne une valeur fausse, la prochaine vérification continue jusqu'à ce qu'une valeur vraie soit retournée. Ceci 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('Element render correctly', async () => {
  const element = await vi.waitUntil(() => document.querySelector('.element'), {
    timeout: 500, // la valeur par défaut est de 1000
    interval: 20, // la valeur par défaut est de 50
  });

  // do something with the element
  expect(element.querySelector('.element-child')).toBeTruthy();
});

vi.hoisted 0.31.0+ ​

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

Dans les modules ES, toutes les instructions import statiques sont remontées en haut du fichier, de sorte que tout code défini avant les imports sera exécuté après l'évaluation de ces derniers.

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

Pour contourner cette limitation, vous pouvez réécrire les imports statiques en imports 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 en utilisant la méthode vi.hoisted.

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

Cette méthode retourne la valeur 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 supporte également les appels asynchrones, même si votre environnement ne prend pas en charge l'attente de niveau supérieur :

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

vi.setConfig ​

  • Type: RuntimeConfig

Met à jour la configuration pour le fichier de test actuel. Cette méthode ne prend en charge que les options de configuration qui affectent le fichier de test en cours :

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

vi.resetConfig ​

  • Type: RuntimeConfig

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

Pager
Page précédenteFonctions Mock
Page suivanteexpect

Publié sous la licence MIT.

Copyright (c) 2024 Mithril Contributors

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

Publié sous la licence MIT.

Copyright (c) 2024 Mithril Contributors