Vi
Vitest fournit des fonctions utilitaires via son assistant vi
. Vous pouvez y accéder globalement si la configuration des globales est activée, ou l'importer depuis vitest
:
import { vi } from 'vitest';
vi.advanceTimersByTime
Type:
(ms: number) => Vitest
Fonctionne de la même manière que
runAllTimers
, mais s'arrête après le délai spécifié en millisecondes. Par exemple, le code suivant affichera1, 2, 3
et ne générera pas d'erreur :tslet i = 0; setInterval(() => console.log(++i), 50); vi.advanceTimersByTime(150);
vi.advanceTimersByTimeAsync
Type:
(ms: number) => Promise<Vitest>
Fonctionne de la même manière que
runAllTimersAsync
, mais s'arrête après le délai spécifié en millisecondes. Cela inclut les temporisateurs définis de manière asynchrone. Par exemple, le code suivant affichera1, 2, 3
et ne générera pas d'erreur :tslet i = 0; setInterval(() => Promise.resolve().then(() => console.log(++i)), 50); await vi.advanceTimersByTimeAsync(150);
vi.advanceTimersToNextTimer
Type:
() => Vitest
Exécute le prochain temporisateur disponible. Utile pour vérifier des conditions entre chaque appel de temporisateur. Vous pouvez chaîner les appels pour gérer vous-même les temporisateurs.
tslet i = 0; setInterval(() => console.log(++i), 50); vi.advanceTimersToNextTimer() // affiche 1 .advanceTimersToNextTimer() // affiche 2 .advanceTimersToNextTimer(); // affiche 3
vi.advanceTimersToNextTimerAsync
Type:
() => Promise<Vitest>
Exécute le prochain temporisateur disponible, même s'il a été défini de manière asynchrone. Utile pour vérifier des conditions entre chaque appel de temporisateur. Vous pouvez chaîner les appels pour gérer vous-même les temporisateurs.
tslet i = 0; setInterval(() => Promise.resolve().then(() => console.log(++i)), 50); vi.advanceTimersToNextTimerAsync() // affiche 1 .advanceTimersToNextTimerAsync() // affiche 2 .advanceTimersToNextTimerAsync(); // affiche 3
vi.getTimerCount
Type:
() => number
Récupère le nombre de temporisateurs en attente.
vi.clearAllMocks
Appelle .mockClear()
sur tous les espions. Efface l'historique des mocks, mais ne réinitialise pas leur implémentation à celle par défaut.
vi.clearAllTimers
Supprime tous les temporisateurs qui sont planifiés pour s'exécuter. Ces temporisateurs ne s'exécuteront jamais.
vi.dynamicImportSettled
Attend que tous les imports dynamiques soient chargés. Utile si vous avez un appel synchrone qui commence à importer un module dynamiquement, et que vous ne pouvez pas attendre autrement.
vi.fn
Type:
(fn?: Function) => Mock
Crée un espion sur une fonction, même sans fonction initiale. 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 fournie, le mock retournera
undefined
lorsqu'il est appelé.tsconst 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.getMockedSystemTime
Type:
() => Date | null
Retourne la date simulée actuelle qui a été définie en utilisant
setSystemTime
. Si la date n'est pas simulée, la fonction retournenull
.
vi.getRealSystemTime
Type:
() => number
Lors de l'utilisation de
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.hoisted
Type:
<T>(factory: () => T) => T
Version: Depuis Vitest 0.31.0
Toutes les déclarations
import
statiques dans les modules ES sont hissées en haut du fichier. Par conséquent, tout code défini avant les imports sera en réalité exécuté après l'évaluation de ces derniers.Cependant, il peut être utile d'invoquer un effet de bord, comme simuler des dates, avant d'importer un module.
Pour contourner cette contrainte, vous pouvez réécrire les imports statiques en imports dynamiques comme ceci :
diffcallFunctionWithSideEffect() - import { value } from './some/module.ts' + const { value } = await import('./some/module.ts')
Lors de l'exécution de
vitest
, vous pouvez le faire automatiquement en utilisant la méthodevi.hoisted
.diff- callFunctionWithSideEffect() import { value } from './some/module.ts' + 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 :tsimport { 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);
vi.mock
Type:
(path: string, factory?: () => unknown) => void
Remplace tous les modules importés à partir du
path
spécifié par un autre module. Vous pouvez utiliser les alias Vite configurés dans ce chemin. L'appel àvi.mock
est hissé, donc peu importe où vous l'appelez, il sera toujours exécuté avant tous les imports. Si vous avez besoin de référencer des variables en dehors de sa portée, vous pouvez les définir à l'intérieur devi.hoisted
et les référencer à l'intérieur devi.mock
.WARNING
vi.mock
fonctionne uniquement pour les modules qui ont été importés avec le mot-cléimport
. Il ne fonctionne pas avecrequire
.Vitest analyse statiquement vos fichiers pour hisser
vi.mock
. Cela signifie que vous ne pouvez pas utiliservi
qui n'a pas été importé directement depuis le packagevitest
(par exemple, depuis un fichier utilitaire). Pour corriger cela, utilisez toujoursvi.mock
avecvi
importé depuisvitest
, ou activez l'option de configurationglobals
.WARNING
La simulation de modules n'est actuellement pas prise en charge dans le mode navigateur. Vous pouvez suivre cette fonctionnalité dans l'issue GitHub.
Si
factory
est défini, tous les imports retourneront son résultat. Vitest appelle la factory une seule fois et met en cache le résultat pour tous les imports suivants jusqu'à ce quevi.unmock
ouvi.doUnmock
soit appelé.Contrairement à
jest
, la factory peut être asynchrone, vous pouvez donc utiliservi.importActual
ou un helper, reçu comme premier argument, à l'intérieur pour obtenir le module original.tsvi.mock('./path/to/module.js', async importOriginal => { const mod = await importOriginal(); return { ...mod, // remplace certains exports namedExport: vi.fn(), }; });
WARNING
vi.mock
est hissé (en d'autres termes, déplacé) en haut du fichier. Cela signifie que, quel que soit l'endroit où vous l'écrivez (que ce soit à l'intérieur debeforeEach
outest
), il sera en fait appelé avant cela.Cela signifie que vous ne pouvez pas utiliser de variables 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 hissé. Attention, il ne simule que les imports suivants.Vous pouvez également référencer des variables définies par la méthode
vi.hoisted
si elle a été déclarée avantvi.mock
:tsimport { 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 de la fonction factory retournée. Il s'agit d'une mise en garde spécifique aux modules ES, par conséquent, la documentation dejest
peut différer carjest
utilise les modules CommonJS. Par exemple,tsvi.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 portant le même nom dans le sous-dossier__mocks__
et l'utilisera comme module réel. Si vous simulez une dépendance, Vitest essaiera de trouver un dossier__mocks__
dans le root du projet (la valeur par défaut estprocess.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, 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
Attention, si vous n'appelez pas
vi.mock
, les modules ne sont pas simulés automatiquement. Pour reproduire le comportement d'automocking de Jest, vous pouvez appelervi.mock
pour chaque module requis à l'intérieur desetupFiles
.S'il n'y a pas de dossier
__mocks__
ou de factory fournie, Vitest importera le module original et auto-simulera tous ses exports. Pour les règles appliquées, voir algorithm.
vi.doMock
Type:
(path: string, factory?: () => unknown) => void
Identique à
vi.mock
, mais il n'est pas hissé en haut du fichier, ce qui vous permet de référencer des variables dans la portée globale du fichier. Le prochain import dynamique du module sera simulé. Cela ne simulera pas les modules qui ont été importés avant cet appel.
// ./increment.js
export function increment(number) {
return number + 1;
}
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'import du prochain module importe celui qui est simulé', async () => {
// l'import original N'A PAS ÉTÉ SIMULÉ (MOCKED), car vi.doMock est évalué APRÈS les imports
expect(increment(1)).toBe(2);
const { increment: mockedIncrement } = await import('./increment.js');
// le nouvel import 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>
Utilitaire de type pour TypeScript. En réalité, retourne simplement l'objet qui a été passé.
Lorsque
partial
esttrue
, il s'attendra à unPartial<T>
comme valeur de retour.tsimport example from './example.js'; vi.mock('./example.js'); test('1+1 equals 2', async () => { vi.mocked(example.calc).mockRestore(); const res = example.calc(1, '+', 1); expect(res).toBe(2); });
vi.importActual
Type:
<T>(path: string) => Promise<T>
Importe le module, en contournant toutes les vérifications pour savoir s'il doit être simulé. Peut être utile si vous souhaitez simuler un module partiellement.
tsvi.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) simulées. Suit les mêmes règles que
vi.mock
. Pour les règles appliquées, voir algorithm.
vi.resetAllMocks
Appelle .mockReset()
sur tous les espions. Efface l'historique des mocks et réinitialise leur implémentation à une fonction vide (retournera undefined
).
vi.resetConfig
Type:
RuntimeConfig
Si
vi.setConfig
a été appelé auparavant, cela réinitialisera la configuration à l'état original.
vi.resetModules
Type:
() => Vitest
Réinitialise le répertoire des modules en effaçant le cache de tous les modules. Cela permettra de réévaluer les modules lors de leur réimportation. Les imports de niveau supérieur ne peuvent pas être réévalués. Peut être utile pour isoler les modules où l'état local entre en conflit entre les tests.
tsimport { vi } from 'vitest'; import { data } from './data.js'; // Ne sera pas réévalué avant chaque test beforeEach(() => { vi.resetModules(); }); test('change state', async () => { const mod = await import('./some/path.js'); // Sera réévalué mod.changeLocalState('new value'); expect(mod.getLocalState()).toBe('new value'); }); test('module has old state', async () => { const mod = await import('./some/path.js'); // Sera réévalué expect(mod.getLocalState()).toBe('old value'); });
WARNING
Ne réinitialise pas le répertoire des mocks. Pour effacer le répertoire des mocks, utilisez vi.unmock
ou vi.doUnmock
.
vi.restoreAllMocks
Appelle .mockRestore()
sur tous les espions. Efface l'historique des mocks et réinitialise leur implémentation à celle d'origine.
vi.stubEnv
Type:
(name: string, value: string) => Vitest
Version: Depuis Vitest 0.26.0
Modifie la valeur de la variable d'environnement sur
process.env
etimport.meta.env
. Vous pouvez restaurer sa valeur en appelantvi.unstubAllEnvs
.
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';
// ne modifie pas les autres envs
import.meta.env.MODE === 'development';
TIP
Vous pouvez également modifier la valeur en lui assignant simplement, mais vous ne pourrez pas utiliser vi.unstubAllEnvs
pour restaurer la valeur précédente :
import.meta.env.MODE = 'test';
vi.unstubAllEnvs
Type:
() => Vitest
Version: Disponible depuis Vitest 0.26.0
Vitest mémorise et stocke la valeur d'origine des variables d'environnement lors du premier appel à
vi.stubEnv
.vi.unstubAllEnvs
restaure ces valeurs mémorisées.
import { vi } from 'vitest';
// `process.env.NODE_ENV` et `import.meta.env.NODE_ENV`
// valent "development" avant l'appel à `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 était 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
.
import { vi } from 'vitest';
// `innerWidth` vaut "0" avant l'appel à 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'assignant 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 d'origine :
globalThis.innerWidth = 100;
// si vous utilisez jsdom ou happy-dom
window.innerWidth = 100;
vi.unstubAllGlobals
Type:
() => Vitest
Version: Disponible depuis Vitest 0.26.0
Restaure toutes les valeurs globales sur
globalThis
/global
(etwindow
/top
/self
/parent
, si vous utilisez l'environnementjsdom
ouhappy-dom
) qui ont été modifiées avecvi.stubGlobal
. Vitest mémorise et stocke la valeur d'origine lors du premier appel àvi.stubGlobal
.vi.unstubAllGlobals
restaure ces valeurs mémorisées.
import { vi } from 'vitest';
const Mock = vi.fn();
// IntersectionObserver est "undefined" avant l'appel à "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;
// lance ReferenceError, car il n'est pas défini
IntersectionObserver === undefined;
vi.runAllTicks
Type:
() => Vitest
Exécute toutes les microtâches qui ont été 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 toutes les minuteries initialisées jusqu'à ce que la file d'attente des minuteries soit vide. Cela signifie que chaque minuterie appelée pendant
runAllTimers
sera déclenchée. En cas d'intervalle infini, une exception sera levée après 10 000 tentatives. Par exemple, cela affichera1, 2, 3
:tslet i = 0; setTimeout(() => console.log(++i)); const interval = setInterval(() => { console.log(++i); if (i === 3) clearInterval(interval); }, 50); vi.runAllTimers();
vi.runAllTimersAsync
Type:
() => Promise<Vitest>
Cette méthode exécute de manière asynchrone toutes les minuteries initialisées jusqu'à ce que la file d'attente des minuteries soit vide. Cela signifie que chaque minuterie appelée pendant
runAllTimersAsync
sera déclenchée, même les minuteries asynchrones. En cas d'intervalle infini, une exception sera levée après 10 000 tentatives. Par exemple, cela afficheraresult
:tssetTimeout(async () => { console.log(await Promise.resolve('result')); }, 100); await vi.runAllTimersAsync();
vi.runOnlyPendingTimers
Type:
() => Vitest
Cette méthode exécute toutes les minuteries qui ont été initialisées après l'appel à
vi.useFakeTimers()
. Elle ne déclenchera aucune minuterie qui a été initialisée pendant son exécution. Par exemple, cela affichera seulement1
:tslet i = 0; setInterval(() => console.log(++i), 50); vi.runOnlyPendingTimers();
vi.runOnlyPendingTimersAsync
Type:
() => Promise<Vitest>
Cette méthode exécute de manière asynchrone toutes les minuteries qui ont été initialisées après l'appel à
vi.useFakeTimers()
, même les minuteries asynchrones. Elle ne déclenchera aucune minuterie qui a été initialisée pendant son exécution. Par exemple, cela affichera2, 3, 3, 1
:tssetTimeout(() => { console.log(1); }, 100); setTimeout(() => { Promise.resolve().then(() => { console.log(2); setInterval(() => { console.log(3); }, 40); }); }, 10); await vi.runOnlyPendingTimersAsync();
vi.setSystemTime
Type:
(date: string | number | Date) => void
Définit la date système à la date spécifiée. Tous les appels à
Date
renverront cette date.Utile si vous devez tester tout ce qui dépend de la date actuelle - par exemple, les appels luxon dans votre code.
tsconst date = new Date(1998, 11, 19); vi.useFakeTimers(); vi.setSystemTime(date); expect(Date.now()).toBe(date.valueOf()); vi.useRealTimers();
vi.setConfig
Type:
RuntimeConfig
Permet de modifier les valeurs de configuration utilisées lors de l'exécution des tests.
vi.spyOn
Type:
<T, K extends keyof T>(object: T, method: K, accessType?: 'get' | 'set') => MockInstance
Crée un espion pour une méthode ou un getter/setter d'un objet.
tslet apples = 0; const cart = { getApples: () => 13, }; const spy = vi.spyOn(cart, 'getApples').mockImplementation(() => apples); apples = 1; expect(cart.getApples()).toBe(1); expect(spy).toHaveBeenCalled(); expect(spy).toHaveReturnedWith(1);
vi.stubGlobal
Type:
(key: keyof globalThis & Window, value: any) => Vitest
Modifie la valeur d'une variable globale. Si vous utilisez
jsdom
ouhappy-dom
, place également la valeur sur l'objetwindow
.Pour plus d'informations, consultez la section "Simulation des globales" (Mocking Globals).
vi.unmock
Type:
(path: string) => void
Supprime le module du registre des modules simulés. Tous les appels à
import
renverront le module d'origine, même s'il a été simulé auparavant. Cet appel est remonté (hoisted) en haut du fichier. Par conséquent, seuls les modules définis danssetupFiles
seront désactivés, par exemple.
vi.doUnmock
Type:
(path: string) => void
Identique à
vi.unmock
, mais n'est pas remonté en haut du fichier. L'importation suivante du module importera le module d'origine au lieu du module simulé. Cela ne désactivera pas les modules importés précédemment.
// ./increment.js
export function increment(number) {
return number + 1;
}
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` renvoie toujours 100
increment(1) === 100;
increment(30) === 100;
// ceci n'est pas remonté, donc une autre importation renverra le module non simulé
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 simulée, maintenant `increment` est la fonction d'origine qui renvoie count + 1
const { increment: unmockedIncrement } = await import('./increment.js');
unmockedIncrement(1) === 2;
unmockedIncrement(30) === 31;
vi.useFakeTimers
Type:
() => Vitest
Pour activer la simulation des minuteries, vous devez appeler cette méthode. Elle interceptera tous les appels ultérieurs aux minuteries (tels que
setTimeout
,setInterval
,clearTimeout
,clearInterval
,nextTick
,setImmediate
,clearImmediate
etDate
), jusqu'à ce quevi.useRealTimers()
soit appelé.La simulation de
nextTick
n'est pas prise en charge lors de l'exécution de Vitest à l'intérieur denode:child_process
en utilisant--no-threads
. NodeJS utiliseprocess.nextTick
en interne dansnode:child_process
et se bloque lorsqu'il est simulé. La simulation denextTick
est prise en charge lors de l'exécution de Vitest avec--threads
.L'implémentation est basée en interne sur
@sinonjs/fake-timers
.TIP
Depuis la version
0.35.0
,vi.useFakeTimers()
ne simule plus automatiquementprocess.nextTick
. Il peut toujours être simulé en spécifiant l'option dans l'argumenttoFake
:vi.useFakeTimers({ toFake: ['nextTick'] })
.
vi.isFakeTimers
Type:
() => boolean
Version: Disponible depuis Vitest 0.34.5
Renvoie
true
si les faux temporisateurs sont activés.
vi.useRealTimers
Type:
() => Vitest
Lorsque vous avez terminé d'utiliser les minuteries simulées, vous pouvez appeler cette méthode pour rétablir les minuteries simulées à leurs implémentations d'origine. Toutes les minuteries qui ont été exécutées auparavant ne seront pas restaurées.
vi.waitFor
- Type:
<T>(callback: WaitForCallback<T>, options?: number | WaitForOptions) => Promise<T>
- Version: Disponible depuis Vitest 0.34.5
Attend l'exécution réussie du callback. Si le callback lève une erreur ou renvoie une promesse rejetée, il continuera d'attendre jusqu'à ce qu'il réussisse ou expire.
Ceci 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.
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
// @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
- Type:
<T>(callback: WaitUntilCallback<T>, options?: number | WaitUntilOptions) => Promise<T>
- Version: Disponible depuis Vitest 0.34.5
Similaire à vi.waitFor
, mais si le callback lève des erreurs, l'exécution est immédiatement interrompue et un message d'erreur est renvoyé. Si le callback renvoie une valeur falsy, la vérification suivante se poursuivra jusqu'à ce qu'une valeur truthy soit renvoyé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.
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
});
// faire quelque chose avec l'élément
expect(element.querySelector('.element-child')).toBeTruthy();
});