Skip to content
Vitest 2
Main Navigation GuideAPIConfigurationMode NavigateurAvancé
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

Référence de l'API de Test

Fonctions Mock

Vi

expect

expectTypeOf

assert

assertType

Sur cette page

vi ​

Vitest met à disposition des fonctions utilitaires via son assistant 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';

Simulation de modules ​

Cette section décrit l'API que vous pouvez utiliser pour simuler un module. Notez que Vitest ne prend pas en charge la simulation 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

Remplace toutes les importations du path spécifié par un autre module. Vous pouvez utiliser les alias Vite configurés dans le chemin. L'appel à vi.mock est remonté (hoisted), il sera donc 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 externes à 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 importés avec le mot-clé import. Il ne fonctionne pas avec require.

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

Vitest ne simulera pas les modules importés dans un fichier de setup car ils sont déjà mis en cache lors de l'exécution du fichier de test. 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.

Si la fonction factory est définie, toutes les importations retourneront son résultat. Vitest n'appelle la factory qu'une seule fois et met en cache les résultats pour 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 helper où la factory est passée en premier argument, et obtenir le module original à l'intérieur.

Depuis Vitest 2.1, vous pouvez également fournir un objet avec une propriété spy au lieu d'une fonction factory. Si spy est true, Vitest simulera automatiquement le module, mais ne remplacera pas l'implémentation des exports. Ceci est utile si vous souhaitez simplement vous assurer qu'une 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 de vérifier 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 plutôt qu'une simple chaîne de caractères 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 conservant les exports facultatifs).

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 certains exports
    total: vi.fn(),
  };
});

En interne, Vitest travaille toujours avec une chaîne de caractères et non avec un objet module.

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

WARNING

vi.mock est remonté (c'est-à-dire déplacé) en haut du fichier. Cela signifie que peu importe où vous l'écrivez (que ce soit à l'intérieur de beforeEach ou test), il sera en fait appelé avant ces blocs.

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

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 remonté. Sachez qu'il ne simulera que les importations qui suivent son appel.

Vous pouvez également référencer des variables définies par la méthode vi.hoisted :

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 simulez un module avec un export par défaut, vous devrez fournir une clé default dans l'objet retourné par la fonction factory. Il s'agit d'une spécificité des 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 simulez, et que la factory n'est pas fournie, Vitest essaiera de trouver un fichier du même nom dans le sous-dossier __mocks__ et de l'utiliser comme module effectif. Si vous simulez une dépendance, Vitest essaiera de trouver un dossier __mocks__ à la racine du projet (par défaut, process.cwd()). Vous pouvez spécifier à 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
// increment.test.js
import { vi } from 'vitest';

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

// increment est un export nommé 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 simulés automatiquement. Pour reproduire le comportement d'automocking de Jest (simulation automatique), 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 simulera 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 remonté en haut du fichier, vous pouvez donc référencer des variables définies dans la portée globale du fichier. La prochaine importation dynamique de ce module sera simulée.

WARNING

Cela ne simulera pas les modules qui ont été importés avant l'appel de cette méthode. N'oubliez pas que toutes les importations statiques en ESM sont toujours remontées, donc placer cet appel avant une importation statique ne garantit pas qu'il sera exécuté avant l'importation :

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

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

// le module n'est pas simulé, 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 simulé', async () => {
  // l'importation originale N'A PAS ÉTÉ SIMULÉ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 retourne le module simulé
  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>

Fonction utilitaire de typage pour TypeScript. Retourne simplement l'objet qui a été passé.

Lorsque partial est true, le type de retour attendu sera Partial<T>. Par défaut, cela indique à TypeScript que seules les valeurs de premier niveau sont simulées. Vous pouvez passer { deep: true } comme deuxième argument pour indiquer à TypeScript que l'objet entier est simulé.

ts
// example.ts
export function add(x: number, y: number): number {
  return x + y;
}

export function fetchSomething(): Promise<Response> {
  return fetch('https://vitest.dev/');
}
ts
// example.test.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('simuler la valeur de retour 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 ignorant toute simulation. Peut être utile si vous souhaitez simuler 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 dont toutes les propriétés (y compris les propriétés imbriquées) sont simulé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 de la liste des modules simulés. Toute importation ultérieure de ce module retournera le module original même s'il a été simulé auparavant. Cet appel est remonté en haut du fichier, il ne désactivera donc la simulation que pour les modules définis dans les setupFiles, par exemple.

vi.doUnmock ​

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

Identique à vi.unmock, mais n'est pas remonté en haut du fichier. La prochaine importation du module importera le module original au lieu du module simulé. Cela ne désactivera pas la simulation des modules précédemment importés.

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

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

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

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

// ceci n'est pas remonté, donc une autre importation retournera un module non simulé
vi.doUnmock('./increment.js');

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

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

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

vi.resetModules ​

  • Type : () => Vitest

Réinitialise la liste des modules en vidant 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 la liste des mocks. Pour effacer la liste 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 déclenche l'importation d'un module et que vous ne pouvez pas attendre sa résolution autrement.

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 lancé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 où elle est résolue.

Simulation 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 fonction spécifique. Chaque fois qu'une fonction est invoquée, elle enregistre 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 retournera undefined lorsqu'il est 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.isMockFunction ​

  • Type : (fn: Function) => boolean

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

vi.clearAllMocks ​

Appellera .mockClear() sur tous les espions. Cela effacera l'historique des appels des mocks, mais ne réinitialisera pas leur implémentation à celle par défaut.

vi.resetAllMocks ​

Appellera .mockReset() sur tous les espions. Cela effacera l'historique des appels des mocks et réinitialisera leur implémentation à une fonction vide (qui retournera undefined).

vi.restoreAllMocks ​

Appellera .mockRestore() sur tous les espions. Cela effacera l'historique des appels des mocks et réinitialisera leur 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 getter/setter d'un objet similaire à vi.fn(). Il retourne une fonction 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

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 d'origine, 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()); // toujours 42 !

TIP

Il n'est pas possible d'espionner les méthodes exportées en Mode Navigateur. Au lieu de cela, vous pouvez espionner chaque méthode exportée en appelant vi.mock("./file-path.js", { spy: true }). Cela simulera chaque export tout en conservant son implémentation d'origine, vous permettant de vérifier 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 exports 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 d'une 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` 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 modifie pas les autres envs
import.meta.env.MODE === 'development';

TIP

Vous pouvez également modifier la valeur en l'affectant simplement, 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 se souvient de la valeur d'origine et la conservera jusqu'à ce que unstubAllEnvs soit appelé à 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 qui a été 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

Modifie la valeur d'une variable globale. Vous pouvez restaurer sa valeur d'origine en appelant 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 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;
// si vous utilisez jsdom ou happy-dom
window.innerWidth = 100;

vi.unstubAllGlobals ​

  • 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'elle est appelée pour la première fois, Vitest se souvient de la valeur d'origine et la conservera jusqu'à ce que unstubAllGlobals soit appelé à 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 pas définie
IntersectionObserver === undefined;

Faux minuteurs ​

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

vi.advanceTimersByTime ​

  • Type : (ms: number) => Vitest

Cette méthode exécutera chaque minuteur démarré jusqu'à ce que le nombre de millisecondes spécifié soit écoulé ou que la file d'attente soit vide - selon ce qui arrive en premier.

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 exécutera chaque minuteur démarré jusqu'à ce que le nombre de millisecondes spécifié soit écoulé ou que la file d'attente soit vide - selon ce qui arrive en premier. 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

Appellera le prochain minuteur disponible. Utile pour faire des assertions entre chaque appel de minuteur. Vous pouvez enchaîner 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>

Appellera le prochain minuteur disponible et attendra qu'il soit résolu s'il a été défini de manière asynchrone. Utile pour faire 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 callbacks actuellement planifiés avec requestAnimationFrame.

ts
let frameRendered = false;

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

vi.advanceTimersToNextFrame();

expect(frameRendered).toBe(true);

vi.getTimerCount ​

  • Type : () => number

Obtient le nombre de minuteurs en attente.

vi.clearAllTimers ​

Supprime tous les minuteurs qui sont planifiés pour s'exécuter. Ces minuteurs ne s'exécuteront jamais à l'avenir.

vi.getMockedSystemTime ​

  • Type : () => Date | null

Retourne la date actuelle simulée qui a été définie à l'aide de setSystemTime. Si la date n'est pas simulée, la méthode retournera null.

vi.getRealSystemTime ​

  • Type : () => number

Lorsque vous utilisez vi.useFakeTimers, 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

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

vi.runAllTimers ​

  • Type : () => Vitest

Cette méthode exécutera chaque minuteur démarré jusqu'à ce que la file d'attente des minuteurs soit vide. Cela signifie que chaque minuteur appelé pendant runAllTimers sera déclenché. Si vous avez un intervalle infini, il lèvera une erreur 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 exécutera de manière asynchrone chaque minuteur démarré jusqu'à ce que la file d'attente des minuteurs soit vide. Cela signifie que chaque minuteur appelé pendant runAllTimersAsync sera déclenché, même les minuteurs asynchrones. Si vous avez un intervalle infini, il lèvera une erreur 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 appellera chaque minuteur qui a été démarré après l'appel de vi.useFakeTimers. Elle ne déclenchera aucun minuteur qui a été démarré pendant 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é démarré après l'appel de vi.useFakeTimers, même les asynchrones. Elle ne déclenchera aucun minuteur qui a été démarré pendant 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 faux minuteurs sont activés, cette méthode simule un changement d'horloge système par l'utilisateur (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 faux minuteurs ne sont pas activés, cette méthode ne simulera 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 chaîne et de 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 la simulation des minuteurs, 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é.

La simulation de nextTick n'est pas prise en charge lors de l'exécution de Vitest à l'intérieur de 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 en interne sur @sinonjs/fake-timers.

TIP

vi.useFakeTimers() ne simule pas automatiquement process.nextTick. Mais vous pouvez l'activer en spécifiant l'option dans l'argument toFake : vi.useFakeTimers({ toFake: ['nextTick'] }).

vi.isFakeTimers ​

  • Type : () => boolean

Retourne true si les faux minuteurs sont activés.

vi.useRealTimers ​

  • Type : () => Vitest

Lorsque vous avez terminé d'utiliser les faux minuteurs, vous pouvez appeler cette méthode pour restaurer les minuteurs simulés à leurs implémentations d'origine. Tous les minuteurs qui ont été planifiés auparavant seront ignorés.

Divers ​

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

vi.waitFor ​

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

Attend que le callback s'exécute avec succès. Si le callback lève une erreur ou retourne une promesse rejetée, il continuera d'attendre jusqu'à ce qu'il réussisse ou expire.

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('Le serveur a 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 callbacks asynchrones

ts
// @vitest-environment jsdom

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

test('L\'élément existe dans le 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) dans chaque callback de vérification.

vi.waitUntil ​

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

Ceci est similaire à vi.waitFor, mais si le callback lève des erreurs, l'exécution est immédiatement interrompue et un message d'erreur est reçu. Si le callback retourne une valeur falsy, la prochaine vérification continuera jusqu'à ce qu'une valeur truthy soit retourné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('L\'élément s\'affiche correctement', 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 remontées en haut du fichier, de sorte que tout code défini avant les importations sera en fait exécuté après l'évaluation des importations.

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 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 en utilisant la méthode vi.hoisted.

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

Cette méthode retourne la valeur qui a été retourné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 le top-level await :

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 affecteront le 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',
    // prend en charge uniquement "sequence.hooks"
  },
});

vi.resetConfig ​

  • Type : RuntimeConfig

Si vi.setConfig a été appelé auparavant, cela réinitialisera la configuration à l'état d'origine.

Pager
Page précédenteFonctions Mock
Page suivanteexpect

Publié sous la licence MIT.

Copyright (c) 2024 Mithril Contributors

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

Publié sous la licence MIT.

Copyright (c) 2024 Mithril Contributors