Skip to content
Vitest 1
Main Navigation PrzewodnikAPIKonfiguracjaZaawansowany
1.6.1
0.34.6

Polski

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

Polski

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

Wygląd

Sidebar Navigation

Przewodnik

Dlaczego Vitest

Wprowadzenie

Funkcje

Przestrzeń robocza

Interfejs Linii Poleceń

Filtrowanie Testów

Reportery

Pokrycie kodu

Snapshot

Mockowanie

Testowanie typów

Interfejs użytkownika Vitest

Tryb przeglądarki

Testowanie w kodzie źródłowym

Kontekst Testowy

Środowisko Testowe

Rozszerzanie Matcherów

Integracje z IDE

Debugowanie

Porównania z innymi narzędziami do uruchamiania testów

Przewodnik migracji

Częste błędy

Poprawa wydajności

API

Dokumentacja API Testów

Funkcje Mockujące

Vi

expect

expectTypeOf

assert

assertType

Konfiguracja

Zarządzanie plikiem konfiguracyjnym Vitest

Konfiguracja Vitest

Na tej stronie

Vi ​

Vitest udostępnia funkcje narzędziowe, które ułatwiają pracę z pomocnikiem vi. Możesz uzyskać do niego dostęp globalnie (gdy konfiguracja globals jest aktywna) lub zaimportować go bezpośrednio z vitest:

js
import { vi } from 'vitest';

Mockowanie Modułów ​

Ta sekcja opisuje API, którego możesz użyć podczas mockowania modułu. Pamiętaj, że Vitest nie obsługuje mockowania modułów importowanych za pomocą require().

vi.mock ​

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

Zastępuje importy modułu o podanej ścieżce (path) innym modułem. W ścieżce możesz użyć skonfigurowanych aliasów Vite. Wywołanie vi.mock jest podnoszone (hoisted), więc jego umiejscowienie w kodzie nie ma znaczenia. Zawsze zostanie wykonane przed wszystkimi importami. Jeśli potrzebujesz odwołać się do zmiennych spoza jego zakresu, możesz zdefiniować je wewnątrz vi.hoisted i odwołać się do nich wewnątrz vi.mock.

WARNING

vi.mock działa tylko dla modułów, które zostały zaimportowane za pomocą słowa kluczowego import. Nie działa z require.

Aby podnieść (hoist) vi.mock, Vitest statycznie analizuje twoje pliki. Oznacza to, że nie możesz użyć vi, które nie zostało bezpośrednio zaimportowane z pakietu vitest (np. z pliku narzędziowego). Użyj vi.mock z vi zaimportowanym z vitest lub włącz opcję konfiguracji globals.

Vitest nie będzie mockował modułów, które zostały zaimportowane wewnątrz pliku setup, ponieważ są one buforowane w momencie uruchomienia pliku testowego. Możesz wywołać vi.resetModules() wewnątrz vi.hoisted, aby wyczyścić wszystkie pamięci podręczne modułów przed uruchomieniem pliku testowego.

WARNING

Tryb przeglądarki obecnie nie obsługuje mockowania modułów. Możesz śledzić postęp prac w GitHub issue.

Jeśli zdefiniowano factory, wszystkie importy zwrócą jego wynik. Vitest wywołuje fabrykę tylko raz i buforuje wyniki dla wszystkich kolejnych importów, dopóki nie zostanie wywołane vi.unmock lub vi.doUnmock.

W przeciwieństwie do jest, fabryka może być asynchroniczna. Możesz użyć vi.importActual lub pomocnika z fabryką przekazaną jako pierwszy argument i uzyskać oryginalny moduł wewnątrz.

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

vi.mock('./path/to/module.js', async importOriginal => {
  const mod = await importOriginal();
  return {
    ...mod,
    // replace some exports
    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,
    // replace some exports
    namedExport: vi.fn(),
  };
});

WARNING

vi.mock jest podnoszone (innymi słowy, przenoszone) na początek pliku. Oznacza to, że gdziekolwiek je napiszesz (czy to wewnątrz beforeEach, czy test), w rzeczywistości zostanie wywołane przed tym.

Oznacza to, że wewnątrz fabryki nie możesz używać zmiennych zdefiniowanych poza nią.

Jeśli potrzebujesz użyć zmiennych wewnątrz fabryki, spróbuj vi.doMock. Działa tak samo, ale nie jest podnoszone. Należy pamiętać, że mockowane są tylko kolejne importy.

Możesz również odwoływać się do zmiennych zdefiniowanych przez metodę vi.hoisted, jeśli została zadeklarowana przed 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

Jeśli mockujesz moduł z eksportem domyślnym, musisz podać klucz default w zwróconym obiekcie funkcji fabryki. Jest to specyficzne dla modułów ES; dlatego dokumentacja jest może się różnić, ponieważ jest używa modułów CommonJS. Na przykład,

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

Jeśli obok pliku, który mockujesz, znajduje się folder __mocks__, a fabryka nie jest dostarczona, Vitest spróbuje znaleźć plik o tej samej nazwie w podfolderze __mocks__ i użyć go jako moduł zastępczy. Jeśli mockujesz zależność, Vitest spróbuje znaleźć folder __mocks__ w root projektu (domyślnie jest to process.cwd()). Możesz poinformować Vitest, gdzie znajdują się zależności, za pomocą opcji konfiguracji deps.moduleDirectories.

Na przykład, masz taką strukturę plików:

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

Jeśli wywołasz vi.mock w pliku testowym bez dostarczonej fabryki, znajdzie plik w folderze __mocks__, aby użyć go jako moduł:

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

Pamiętaj, że jeśli nie wywołasz vi.mock, moduły nie są mockowane automatycznie. Aby odtworzyć zachowanie automatycznego mockowania Jest, możesz wywołać vi.mock dla każdego wymaganego modułu wewnątrz setupFiles.

Jeśli nie ma folderu __mocks__ ani dostarczonej fabryki, Vitest zaimportuje oryginalny moduł i automatycznie zmockuje wszystkie jego eksporty. Aby zapoznać się z zastosowanymi regułami, zobacz algorytm.

vi.doMock ​

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

Działa tak samo jak vi.mock, ale nie jest podnoszone (hoisted) na początek pliku, więc możesz odwoływać się do zmiennych w globalnym zakresie pliku. Kolejny dynamiczny import modułu zostanie zmockowany.

WARNING

To nie spowoduje zmockowania modułów zaimportowanych przed tym wywołaniem. Nie zapominaj, że wszystkie statyczne importy w ESM są zawsze podnoszone, więc umieszczenie tego przed statycznym importem nie wymusi jego wywołania przed importem:

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 ​

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

Pomocnik typów dla TypeScript. Po prostu zwraca przekazany obiekt.

Gdy partial ma wartość true, oczekuje Partial<T> jako wartości zwracanej. Domyślnie sprawi to tylko, że TypeScript uwierzy, że wartości pierwszego poziomu są mockowane. Możesz przekazać { deep: true } jako drugi argument, aby poinformować TypeScript, że cały obiekt jest mockowany, jeśli tak jest w rzeczywistości.

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 ​

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

Importuje moduł, pomijając wszystkie sprawdzenia, czy powinien być mockowany. Może być przydatne, jeśli chcesz częściowo mockować moduł.

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

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

vi.importMock ​

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

Importuje moduł ze wszystkimi jego właściwościami (w tym zagnieżdżonymi właściwościami) zmockowanymi. Przestrzega tych samych zasad, co vi.mock. Aby zapoznać się z zastosowanymi regułami, zobacz algorytm.

vi.unmock ​

  • Typ: (path: string) => void

Usuwa moduł z rejestru mockowanych modułów. Wszystkie wywołania importu zwrócą oryginalny moduł, nawet jeśli był wcześniej mockowany. To wywołanie jest podnoszone (hoisted) na początek pliku, więc odmockuje tylko moduły, które zostały zdefiniowane na przykład w setupFiles.

vi.doUnmock ​

  • Typ: (path: string) => void

Działa tak samo jak vi.unmock, ale nie jest podnoszone (hoisted) na początek pliku. Kolejny import modułu zaimportuje oryginalny moduł zamiast mocka. To nie odmockuje wcześniej zaimportowanych modułów.

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 ​

  • Typ: () => Vitest

Resetuje rejestr modułów, czyszcząc pamięć podręczną wszystkich modułów. Pozwala to na ponowną ocenę modułów po ponownym zaimportowaniu. Importy najwyższego poziomu nie mogą być ponownie ocenione. Może to być przydatne do izolowania modułów, w których stan lokalny powoduje konflikty między testami.

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

Nie resetuje rejestru mocków. Aby wyczyścić rejestr mocków, użyj vi.unmock lub vi.doUnmock.

vi.dynamicImportSettled ​

Czeka na załadowanie wszystkich dynamicznych importów. Przydatne, jeśli masz synchroniczne wywołanie, które rozpoczyna importowanie modułu, na który inaczej nie możesz czekać.

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

Jeśli podczas dynamicznego importu inicjowany jest inny dynamiczny import, ta metoda poczeka, aż wszystkie zostaną rozwiązane.

Ta metoda poczeka również na następny tick setTimeout po rozwiązaniu importu, więc wszystkie synchroniczne operacje powinny zostać zakończone do czasu jego rozwiązania.

Mockowanie Funkcji i Obiektów ​

Ta sekcja opisuje, jak pracować z mockami metod i zastępować zmienne środowiskowe i globalne.

vi.fn ​

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

Tworzy szpiega (spy) na funkcji, chociaż można go zainicjować bez podawania funkcji. Za każdym razem, gdy funkcja jest wywoływana, przechowuje swoje argumenty wywołania, wartości zwracane i instancje. Ponadto możesz manipulować jego zachowaniem za pomocą metod. Jeśli nie podano funkcji, mock zwróci undefined po wywołaniu.

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 ​

  • Typ: (fn: Function) => boolean

Sprawdza, czy dany parametr jest funkcją mock. Jeśli używasz TypeScript, zawęzi również jego typ.

vi.clearAllMocks ​

Wywoła .mockClear() dla wszystkich szpiegów (spies). Spowoduje to wyczyszczenie historii mocków, ale implementacja nie zostanie zresetowana do domyślnej.

vi.resetAllMocks ​

Wywoła .mockReset() dla wszystkich szpiegów (spies). To wyczyści historię mocków i zresetuje jego implementację do pustej funkcji (zwróci undefined).

vi.restoreAllMocks ​

Wywoła .mockRestore() dla wszystkich szpiegów (spies). To wyczyści historię mocków i zresetuje jego implementację do oryginalnej.

vi.spyOn ​

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

Tworzy szpiega (spy) na metodzie lub getterze/setterze obiektu, podobnie jak vi.fn(). Zwraca funkcję mock.

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

Możesz wywołać vi.restoreAllMocks wewnątrz afterEach (lub włączyć test.restoreMocks), aby przywrócić wszystkie metody do ich oryginalnych implementacji. To przywróci oryginalny deskryptor obiektu, więc nie będziesz mógł zmienić implementacji metody:

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

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

Zmienia wartość zmiennych środowiskowych w process.env oraz import.meta.env. Możesz przywrócić jej wartość, wywołując vi.unstubAllEnvs.

ts
import { vi } from 'vitest';

// `process.env.NODE_ENV` and `import.meta.env.NODE_ENV`
// są "development" przed wywołaniem "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

Wartość można również zmienić przez proste przypisanie. Jednak w takim przypadku nie będzie można użyć vi.unstubAllEnvs, aby przywrócić poprzednią wartość.

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

vi.unstubAllEnvs 0.26.0+ ​

  • Typ: () => Vitest

Przywraca wszystkie wartości import.meta.env i process.env, które zostały zmienione za pomocą vi.stubEnv. Przy pierwszym wywołaniu, Vitest zapamiętuje oryginalną wartość i przechowuje ją. Zostanie ona przywrócona, gdy unstubAllEnvs zostanie wywołane ponownie.

ts
import { vi } from 'vitest';

// `process.env.NODE_ENV` and `import.meta.env.NODE_ENV`
// są "development" przed wywołaniem 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 ​

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

Zmienia wartość zmiennej globalnej. Możesz przywrócić jej oryginalną wartość, wywołując 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

Wartość można również zmienić przez proste przypisanie jej do globalThis lub window (jeśli używasz środowiska jsdom lub happy-dom), ale nie będziesz mógł użyć vi.unstubAllGlobals, aby przywrócić oryginalną wartość:

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

vi.unstubAllGlobals 0.26.0+ ​

  • Typ: () => Vitest

Przywraca wszystkie globalne wartości w globalThis/global (oraz window/top/self/parent, jeśli używasz środowiska jsdom lub happy-dom), które zostały zmienione za pomocą vi.stubGlobal. Przy pierwszym wywołaniu, Vitest zapamiętuje oryginalną wartość i przechowuje ją. Zostanie ona przywrócona, gdy unstubAllGlobals zostanie wywołane ponownie.

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;

Fałszywe Timery ​

Ta sekcja opisuje, jak pracować z fałszywymi timerami.

vi.advanceTimersByTime ​

  • Typ: (ms: number) => Vitest

Ta metoda przesuwa zegar o określoną liczbę milisekund, wywołując wszystkie timery, które powinny zostać uruchomione w tym czasie. Działa do momentu, aż upłynie określona liczba milisekund lub kolejka timerów będzie pusta – w zależności od tego, co nastąpi wcześniej.

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 ​

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

Ta metoda asynchronicznie przesuwa zegar o określoną liczbę milisekund, wywołując wszystkie timery, które powinny zostać uruchomione w tym czasie. Działa do momentu, aż upłynie określona liczba milisekund lub kolejka timerów będzie pusta – w zależności od tego, co nastąpi wcześniej. Dotyczy to również timerów ustawionych asynchronicznie.

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 ​

  • Typ: () => Vitest

Wywołuje następny timer w kolejce. Przydatne do sprawdzania stanu między wywołaniami timerów. Można użyć łańcuchowego wywoływania tej metody, aby precyzyjnie kontrolować postęp timerów.

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 ​

  • Typ: () => Promise<Vitest>

Wywołuje następny timer w kolejce i czeka na jego rozwiązanie, jeśli został ustawiony asynchronicznie. Przydatne do sprawdzania stanu po każdym wywołaniu timera.

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 ​

  • Typ: () => number

Zwraca liczbę oczekujących timerów.

vi.clearAllTimers ​

Usuwa wszystkie timery, które oczekują na uruchomienie. Te timery nie zostaną uruchomione.

vi.getMockedSystemTime ​

  • Typ: () => Date | null

Zwraca symulowaną datę systemową ustawioną za pomocą setSystemTime. Jeśli data nie została zamockowana, metoda zwraca null.

vi.getRealSystemTime ​

  • Typ: () => number

Podczas korzystania z vi.useFakeTimers, wywołania Date.now są mockowane. Jeśli potrzebujesz uzyskać rzeczywisty czas w milisekundach, możesz wywołać tę funkcję.

vi.runAllTicks ​

  • Typ: () => Vitest

Wywołuje wszystkie mikrozadania umieszczone w kolejce przez process.nextTick. Spowoduje to również uruchomienie wszystkich mikrozadań zaplanowanych przez te mikrozadania.

vi.runAllTimers ​

  • Typ: () => Vitest

Ta metoda wywołuje wszystkie zainicjowane timery, aż kolejka timerów będzie pusta. Oznacza to, że wszystkie timery wywołane w trakcie działania runAllTimers zostaną również wykonane. W przypadku nieskończonego interwału, po 10 000 próbach zostanie zgłoszony wyjątek (można to skonfigurować za pomocą 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 ​

  • Typ: () => Promise<Vitest>

Ta metoda asynchronicznie wywołuje wszystkie zainicjowane timery, aż kolejka timerów będzie pusta. Oznacza to, że wszystkie timery wywołane w trakcie działania runAllTimersAsync zostaną również wykonane, w tym timery asynchroniczne. W przypadku nieskończonego interwału, po 10 000 próbach zostanie zgłoszony wyjątek (można to skonfigurować za pomocą fakeTimers.loopLimit).

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

await vi.runAllTimersAsync();

// log: result

vi.runOnlyPendingTimers ​

  • Typ: () => Vitest

Ta metoda wywołuje tylko te timery, które zostały zainicjowane po wywołaniu vi.useFakeTimers. Timery zainicjowane w trakcie jej działania nie zostaną uruchomione.

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

vi.runOnlyPendingTimers();

// log: 1

vi.runOnlyPendingTimersAsync ​

  • Typ: () => Promise<Vitest>

Ta metoda asynchronicznie wywołuje tylko te timery, które zostały zainicjowane po wywołaniu vi.useFakeTimers, w tym timery asynchroniczne. Timery zainicjowane w trakcie jej działania nie zostaną uruchomione.

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 ​

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

Gdy włączone są fałszywe timery, ta metoda symuluje zmianę czasu systemowego (wpływa to na API związane z datą, takie jak hrtime, performance.now lub new Date()) - jednak nie uruchamia żadnych timerów. Jeśli fałszywe timery nie są włączone, ta metoda mockuje tylko wywołania Date.*.

Przydatne, jeśli musisz przetestować kod, który zależy od bieżącej daty - na przykład wywołania Luxon wewnątrz twojego kodu.

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 ​

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

Aby włączyć mockowanie timerów, należy wywołać tę metodę. Spowoduje to, że wszystkie kolejne wywołania timerów (takich jak setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, clearImmediate i Date) będą mockowane, aż do wywołania vi.useRealTimers().

Mockowanie nextTick nie jest obsługiwane podczas uruchamiania Vitest wewnątrz node:child_process za pomocą --pool=forks. NodeJS używa process.nextTick wewnętrznie w node:child_process i zawiesza się, gdy jest mockowany. Mockowanie nextTick jest obsługiwane podczas uruchamiania Vitest z --pool=threads.

Implementacja opiera się wewnętrznie na @sinonjs/fake-timers.

TIP

Od wersji 0.35.0 vi.useFakeTimers() nie mockuje już automatycznie process.nextTick. Można go nadal mockować, określając opcję w argumencie toFake: vi.useFakeTimers({ toFake: ['nextTick'] }).

vi.isFakeTimers 0.34.5+ ​

  • Typ: () => boolean

Zwraca true, jeśli fałszywe timery są włączone.

vi.useRealTimers ​

  • Typ: () => Vitest

Po zakończeniu korzystania z fałszywych timerów, możesz wywołać tę metodę, aby przywrócić oryginalne implementacje zamockowanych timerów. Wszystkie timery, które zostały wcześniej zaplanowane, zostaną odrzucone.

Inne funkcje ​

Zestaw przydatnych funkcji pomocniczych udostępnianych przez Vitest.

vi.waitFor 0.34.5+ ​

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

Czeka na pomyślne wykonanie funkcji zwrotnej. Jeśli funkcja zwrotna zgłosi błąd lub zwróci odrzuconą obietnicę, oczekiwanie będzie kontynuowane, aż zakończy się powodzeniem lub upłynie limit czasu.

Jest to szczególnie przydatne, gdy trzeba poczekać na zakończenie asynchronicznej operacji, na przykład, gdy uruchamiasz serwer i musisz poczekać, aż będzie gotowy.

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, // domyślnie 1000
      interval: 20, // domyślnie 50
    }
  );
  expect(server.isReady).toBe(true);
});

Działa również dla asynchronicznych funkcji zwrotnych

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, // domyślnie 1000
      interval: 20, // domyślnie 50
    }
  );
  expect(element).toBeInstanceOf(HTMLElement);
});

Jeśli używany jest vi.useFakeTimers, vi.waitFor automatycznie wywołuje vi.advanceTimersByTime(interval) w każdym wywołaniu funkcji zwrotnej sprawdzającej.

vi.waitUntil 0.34.5+ ​

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

Działa podobnie do vi.waitFor, ale jeśli funkcja zwrotna zgłosi jakikolwiek błąd, wykonanie zostanie natychmiast przerwane, a błąd zostanie przekazany dalej. Jeśli funkcja zwrotna zwróci wartość fałszywą, oczekiwanie będzie kontynuowane, aż zwróci wartość prawdziwą. Jest to przydatne, gdy trzeba poczekać, aż coś zaistnieje, zanim przejdziesz do następnego kroku.

Spójrz na poniższy przykład. Możemy użyć vi.waitUntil, aby poczekać, aż element pojawi się na stronie, a następnie możemy coś z nim zrobić.

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

test('Element render correctly', async () => {
  const element = await vi.waitUntil(() => document.querySelector('.element'), {
    timeout: 500, // domyślnie 1000
    interval: 20, // domyślnie 50
  });

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

vi.hoisted 0.31.0+ ​

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

Wszystkie statyczne instrukcje import w modułach ES są przenoszone na początek pliku, więc kod zdefiniowany przed importami zostanie faktycznie wykonany po obliczeniu importów.

Jednak może być przydatne wywołanie niektórych efektów ubocznych, takich jak mockowanie dat przed zaimportowaniem modułu.

Aby obejść to ograniczenie, możesz przepisać statyczne importy na dynamiczne w następujący sposób:

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

Podczas uruchamiania vitest możesz to zrobić automatycznie za pomocą metody vi.hoisted.

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

Ta metoda zwraca wartość, która została zwrócona z fabryki. Możesz użyć tej wartości w swoich funkcjach tworzących vi.mock, jeśli potrzebujesz łatwego dostępu do lokalnie zdefiniowanych zmiennych:

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

Zauważ, że ta metoda może być również wywoływana asynchronicznie, nawet jeśli twoje środowisko nie obsługuje top-level await:

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

vi.setConfig ​

  • Typ: RuntimeConfig

Aktualizuje konfigurację dla aktualnie przetwarzanego pliku testowego. Ta metoda obsługuje tylko opcje konfiguracyjne, które wpłyną na bieżący plik testowy:

ts
vi.setConfig({
  allowOnly: true,
  testTimeout: 10_000,
  hookTimeout: 10_000,
  clearMocks: true,
  restoreMocks: true,
  fakeTimers: {
    now: new Date(2021, 11, 19),
    // obsługuje wszystkie właściwości obiektu
  },
  maxConcurrency: 10,
  sequence: {
    hooks: 'stack',
    // obsługuje tylko "sequence.hooks"
  },
});

vi.resetConfig ​

  • Typ: RuntimeConfig

Jeśli wcześniej wywołano vi.setConfig, spowoduje to zresetowanie konfiguracji do stanu pierwotnego.

Pager
Poprzednia stronaFunkcje Mockujące
Następna stronaexpect

Opublikowano na licencji MIT.

Copyright (c) 2024 Mithril Contributors

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

Opublikowano na licencji MIT.

Copyright (c) 2024 Mithril Contributors