vi
Vitest, vi yardımcı fonksiyonu aracılığıyla size yardımcı olacak çeşitli işlevler sunar. Bu işlevlere global olarak erişebilirsiniz (globals yapılandırması etkinleştirildiğinde) veya doğrudan vitest'ten içe aktarabilirsiniz:
import { vi } from 'vitest';Modülleri Mock Etme
Bu bölüm, bir modülü mock ederken kullanabileceğiniz API'yi açıklar. Vitest'in require() kullanılarak içe aktarılan modülleri mock etmeyi desteklemediğini unutmayın.
vi.mock
- Tür:
(path: string, factory?: MockOptions | ((importOriginal: () => unknown) => unknown)) => void - Tür:
<T>(path: Promise<T>, factory?: MockOptions | ((importOriginal: () => T) => T | Promise<T>)) => void
Belirtilen path'ten içe aktarılan tüm modülleri başka bir modülle değiştirir. Yol içinde yapılandırılmış Vite takma adlarını kullanabilirsiniz. vi.mock çağrısı yükseltilir (hoisted), bu nedenle nerede çağırdığınız önemli değildir. Her zaman tüm içe aktarmalardan önce yürütülecektir. Kapsamı dışındaki bazı değişkenlere başvurmanız gerekiyorsa, bunları vi.hoisted içinde tanımlayabilir ve vi.mock içinde bunlara başvurabilirsiniz.
WARNING
vi.mock yalnızca import anahtar kelimesiyle içe aktarılan modüller için çalışır. require ile çalışmaz.
vi.mock'u yükseltmek için Vitest dosyalarınızı statik olarak analiz eder. Bu, doğrudan vitest paketinden (örneğin, bazı yardımcı dosyalardan) içe aktarılmayan vi'nin kullanılamayacağı anlamına gelir. vi.mock'u vitest'ten içe aktarılan vi ile kullanın veya globals yapılandırma seçeneğini etkinleştirin.
Vitest, bir kurulum dosyası içinde içe aktarılan modülleri mock etmeyecektir çünkü bir test dosyası çalışırken önbelleğe alınırlar. Bir test dosyası çalıştırmadan önce tüm modül önbelleklerini temizlemek için vi.hoisted içinde vi.resetModules() çağırabilirsiniz.
factory fonksiyonu tanımlanmışsa, tüm içe aktarmalar bu fonksiyonun sonucunu döndürecektir. Vitest, factory'yi yalnızca bir kez çağırır ve vi.unmock veya vi.doUnmock çağrılana kadar sonraki içe aktarmalar için sonuçları önbelleğe alır.
jest'in aksine, factory asenkron olabilir. vi.importActual veya factory'nin ilk argüman olarak geçirildiği bir yardımcıyı kullanabilir ve içinde orijinal modülü alabilirsiniz.
Vitest 2.1 itibarıyla, bir factory fonksiyonu yerine spy özelliği olan bir nesne de sağlayabilirsiniz. Eğer spy true ise, Vitest modülü her zamanki gibi otomatik olarak mock edecektir, ancak dışa aktarmaların uygulamasını geçersiz kılmayacaktır. Bu, yalnızca dışa aktarılan yöntemin başka bir yöntem tarafından doğru bir şekilde çağrıldığını doğrulamak istediğiniz zaman faydalıdır.
import { calculator } from './src/calculator.ts';
vi.mock('./src/calculator.ts', { spy: true });
// orijinal uygulamayı çağırır,
// ancak davranışı daha sonra doğrulamaya izin verir
const result = calculator(1, 2);
expect(result).toBe(3);
expect(calculator).toHaveBeenCalledWith(1, 2);
expect(calculator).toHaveReturned(3);Vitest ayrıca daha iyi IDE desteği için vi.mock ve vi.doMock yöntemlerinde bir dize yerine bir modül promise'i de destekler. Dosya taşındığında, yol güncellenecek ve importOriginal türü otomatik olarak devralır. Bu imzanın kullanılması, factory dönüş türünün orijinal modülle uyumlu olmasını da zorunlu kılar (dışa aktarmaları isteğe bağlı tutarak).
// @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(); // tür çıkarıldı
// ^?
return {
...mod,
// bazı dışa aktarmaları değiştir
total: vi.fn(),
};
});Vitest, temelde hala bir dize üzerinde çalışır, bir modül nesnesi üzerinde değil.
Ancak, tsconfig.json içinde yapılandırılmış paths takma adlarıyla TypeScript kullanıyorsanız, derleyici içe aktarma türlerini doğru şekilde çözümleyemez. Bunun çalışması için, tüm takma adlandırılmış içe aktarmaları, karşılık gelen göreceli yollarıyla değiştirdiğinizden emin olun. Örneğin, import('@/module') yerine import('./path/to/module.js') kullanın.
WARNING
vi.mock dosyanın en üstüne yükseltilir (yani, taşınır). Bu, ne zaman yazarsanız yazın (ister beforeEach ister test içinde olsun), aslında ondan önce çağrılacağı anlamına gelir.
Bu aynı zamanda, factory dışında tanımlanmış herhangi bir değişkeni factory içinde kullanamayacağınız demektir.
Factory içinde değişkenler kullanmanız gerekiyorsa, vi.doMock kullanmayı deneyin. Aynı şekilde çalışır ancak yükseltilmez. Yalnızca sonraki içe aktarmaları mock ettiğini akılda tutun.
Ayrıca, vi.mock'tan önce tanımlanmışsa vi.hoisted yöntemiyle tanımlanmış değişkenlere başvurabilirsiniz:
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
Varsayılan dışa aktarması olan bir modülü mock ediyorsanız, döndürülen factory fonksiyonu nesnesi içinde bir default anahtarı sağlamanız gerekir. Bu, ES modülüne özgü bir istisnadır; dolayısıyla, jest CommonJS modülleri kullandığı için jest belgeleri farklılık gösterebilir. Örneğin,
vi.mock('./path/to/module.js', () => {
return {
default: { myDefaultKey: vi.fn() },
namedExport: vi.fn(),
// vb...
};
});Mock ettiğiniz dosyanın yanında bir __mocks__ klasörü varsa ve factory sağlanmamışsa, Vitest __mocks__ alt klasöründe aynı ada sahip bir dosya bulmaya çalışacak ve bunu gerçek bir modül olarak kullanır. Bir bağımlılığı mock ediyorsanız, Vitest projenin kökünde (varsayılan process.cwd()) bir __mocks__ klasörü bulmaya çalışır. Bağımlılıkların nerede bulunduğunu deps.moduleDirectories yapılandırma seçeneği aracılığıyla Vitest'e belirtebilirsiniz.
Örneğin, şu dosya yapısına sahipsiniz:
- __mocks__
- axios.js
- src
__mocks__
- increment.js
- increment.js
- tests
- increment.test.jsBir test dosyasında factory veya seçenekler sağlamadan vi.mock çağrısı yaparsanız, modül olarak kullanılacak __mocks__ klasöründe bir dosya bulur:
// increment.test.js
import { vi } from 'vitest';
// axios, `__mocks__/axios.js`'ten varsayılan bir dışa aktarmadır
import axios from 'axios';
// increment, `src/__mocks__/increment.js`'ten adlandırılmış bir dışa aktarmadır
import { increment } from '../increment.js';
vi.mock('axios');
vi.mock('../increment.js');
axios.get(`/apples/${increment(1)}`);WARNING
vi.mock çağrısı yapmazsanız, modüllerin otomatik olarak mock edilmediğini akılda tutun. Jest'in otomatik mock davranışının benzerini yapmak için, setupFiles içinde her gerekli modül için vi.mock çağırabilirsiniz.
__mocks__ klasörü veya sağlanan bir factory yoksa, Vitest orijinal modülü içe aktaracak ve tüm dışa aktarmalarını otomatik olarak mock eder. Uygulanan kurallar için algoritma bölümüne bakın.
vi.doMock
- Tür:
(path: string, factory?: MockOptions | ((importOriginal: () => unknown) => unknown)) => void - Tür:
<T>(path: Promise<T>, factory?: MockOptions | ((importOriginal: () => T) => T | Promise<T>)) => void
vi.mock ile aynıdır, ancak dosyanın en üstüne yükseltilmez, bu nedenle global dosya kapsamındaki değişkenlere başvurabilirsiniz. Modülün bir sonraki dinamik içe aktarımı mock edilecektir.
WARNING
Bu, bundan önce içe aktarılan modülleri mock etmez. ESM'deki tüm statik içe aktarmaların her zaman yükseltildiğini akılda tutun, bu nedenle bunu statik içe aktarmadan önce koymak, içe aktarmadan önce çağrılmasını zorlamaz:
vi.doMock('./increment.js'); // bu, içe aktırma ifadesinden _sonra_ çağrılır
import { increment } from './increment.js';// ./increment.js
export function increment(number) {
return number + 1;
}import { beforeEach, test } from 'vitest';
import { increment } from './increment.js';
// modül mock edilmedi, çünkü vi.doMock henüz çağrılmadı
increment(1) === 2;
let mockedIncrement = 100;
beforeEach(() => {
// bir factory içinde değişkenlere erişebilirsiniz
vi.doMock('./increment.js', () => ({ increment: () => ++mockedIncrement }));
});
test('sonraki modülü içe aktarmak mock edilmiş olanı içe aktarır', async () => {
// orijinal içe aktarma MOCK EDİLMEDİ, çünkü vi.doMock içe aktarmalardan SONRA değerlendirilir
expect(increment(1)).toBe(2);
const { increment: mockedIncrement } = await import('./increment.js');
// yeni dinamik içe aktarma mock edilmiş modülü döndürür
expect(mockedIncrement(1)).toBe(101);
expect(mockedIncrement(1)).toBe(102);
expect(mockedIncrement(1)).toBe(103);
});vi.mocked
- Tür:
<T>(obj: T, deep?: boolean) => MaybeMockedDeep<T> - Tür:
<T>(obj: T, options?: { partial?: boolean; deep?: boolean }) => MaybePartiallyMockedDeep<T>
TypeScript için tür yardımcısı. Yalnızca geçirilen nesneyi döndürür.
partial true olduğunda, dönüş değeri olarak bir Partial<T> bekleyecektir. Varsayılan olarak, bu yalnızca TypeScript'in ilk seviye değerlerinin mock edildiğine inanmasını sağlayacaktır. Tüm nesnenin mock edildiğini TypeScript'e söylemek için ikinci argüman olarak { deep: true } geçirebilirsiniz, eğer gerçekten öyleyse.
// example.ts
export function add(x: number, y: number): number {
return x + y;
}
export function fetchSomething(): Promise<Response> {
return fetch('https://vitest.dev/');
}// example.test.ts
import * as example from './example';
vi.mock('./example');
test('1 + 1 eşittir 10', async () => {
vi.mocked(example.add).mockReturnValue(10);
expect(example.add(1, 1)).toBe(10);
});
test('mock return value with only partially correct typing', 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 }) // bu bir tür hatasıdır
});vi.importActual
- Tür:
<T>(path: string) => Promise<T>
Modülü içe aktarır, mock edilip edilmeyeceğiyle ilgili tüm kontrolleri atar. Modülü kısmen mock etmek istediğiniz zaman kullanışlı olabilir.
vi.mock('./example.js', async () => {
const axios = await vi.importActual('./example.js');
return { ...axios, get: vi.fn() };
});vi.importMock
- Tür:
<T>(path: string) => Promise<MaybeMockedDeep<T>>
Tüm özelliklerinin (iç içe geçmiş özellikler dahil) mock edildiği bir modülü içe aktarır. vi.mock ile aynı kuralları izler. Uygulanan kurallar için algoritma bölümüne bakın.
vi.unmock
- Tür:
(path: string | Promise<Module>) => void
Modülü mock edilmiş kayıt defterinden kaldırır. İçe aktarma için yapılan tüm çağrılar, daha önce mock edilmiş olsa bile orijinal modülü döndürür. Bu çağrı dosyanın en üstüne yükseltilir, bu nedenle yalnızca setupFiles içinde tanımlanmış modülleri mock etmez.
vi.doUnmock
- Tür:
(path: string | Promise<Module>) => void
vi.unmock ile aynıdır, ancak dosyanın en üstüne yükseltilmez. Modülün bir sonraki içe aktarımı, mock yerine orijinal modülü içe aktarır. Bu, daha önce içe aktarılan modülleri mock etmez.
// ./increment.js
export function increment(number) {
return number + 1;
}import { increment } from './increment.js';
// increment zaten mock edildi, çünkü vi.mock yükseltildi
increment(1) === 100;
// bu yükseltildi ve factory 1. satırdaki içe aktarmadan önce çağrıldı
vi.mock('./increment.js', () => ({ increment: () => 100 }));
// tüm çağrılar mock edildi ve `increment` her zaman 100 döndürür
increment(1) === 100;
increment(30) === 100;
// bu yükseltilmedi, bu nedenle diğer içe aktarma mock edilmemiş modülü döndürür
vi.doUnmock('./increment.js');
// bu HALA 100 döndürür, çünkü `vi.doUnmock` bir modülü yeniden değerlendirmez
increment(1) === 100;
increment(30) === 100;
// bir sonraki içe aktarma mock edilmedi, şimdi `increment` sayıyı + 1 döndüren orijinal fonksiyondur
const { increment: unmockedIncrement } = await import('./increment.js');
unmockedIncrement(1) === 2;
unmockedIncrement(30) === 31;vi.resetModules
- Tür:
() => Vitest
Tüm modüllerin önbelleğini temizleyerek modül kayıt defterini sıfırlar. Bu, modüllerin yeniden içe aktarıldığında yeniden değerlendirilmesine olanak tanır. Üst düzey içe aktarmalar yeniden değerlendirilemez. Yerel durumun testler arasında çakıştığı modülleri izole etmek için kullanışlı olabilir.
import { vi } from 'vitest';
import { data } from './data.js'; // Her testten önce yeniden değerlendirilmez
beforeEach(() => {
vi.resetModules();
});
test('durumu değiştir', async () => {
const mod = await import('./some/path.js'); // Yeniden değerlendirilir
mod.changeLocalState('new value');
expect(mod.getLocalState()).toBe('new value');
});
test('modül eski duruma sahip', async () => {
const mod = await import('./some/path.js'); // Yeniden değerlendirilir
expect(mod.getLocalState()).toBe('old value');
});WARNING
Mock kayıt defterini sıfırlamaz. Mock kayıt defterini temizlemek için vi.unmock veya vi.doUnmock kullanın.
vi.dynamicImportSettled
Tüm içe aktarmaların yüklenmesini bekler. Aksi takdirde bekleyemeyeceğiniz bir modülü içe aktarmaya başlayan senkron bir çağrınız varsa kullanışlıdır.
import { expect, test } from 'vitest';
// Promise döndürülmediği için içe aktarmayı izleyemez
function renderComponent() {
import('./component.js').then(({ render }) => {
render();
});
}
test('işlemler çözüldü', async () => {
renderComponent();
await vi.dynamicImportSettled();
expect(document.querySelector('.component')).not.toBeNull();
});TIP
Dinamik bir içe aktarma sırasında başka bir dinamik içe aktarma başlatılırsa, bu yöntem hepsi çözülene kadar bekler.
Bu yöntem ayrıca, içe aktarma çözüldükten sonra bir sonraki setTimeout tikini bekler, böylece tüm senkron işlemler çözüldüğünde tamamlanmış olur.
Fonksiyonları ve Nesneleri Mock Etme
Bu bölüm, yöntem mock'larıyla nasıl çalışılacağını ve çevresel ve global değişkenlerin nasıl değiştirileceğini açıklar.
vi.fn
- Tür:
(fn?: Function) => Mock
Bir fonksiyon üzerinde bir spy oluşturur, ancak bir tane olmadan başlatılabilir. Bir fonksiyon her çağrıldığında, çağrı argümanlarını, dönüşlerini ve örneklerini saklar. Ayrıca, yöntemlerle davranışını manipüle edebilirsiniz. Fonksiyon verilmezse, mock çağrıldığında undefined döndürür.
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
- Tür:
(fn: Function) => boolean
Verilen bir parametrenin bir mock fonksiyonu olup olmadığını kontrol eder. TypeScript kullanıyorsanız, türünü de daraltır.
vi.clearAllMocks
Tüm spy'larda .mockClear() çağrısı yapar. Bu, mock geçmişini temizler, ancak uygulamasını varsayılana sıfırlamaz.
vi.resetAllMocks
Tüm spy'larda .mockReset() çağrısı yapar. Bu, mock geçmişini temizler ve uygulamasını boş bir fonksiyona sıfırlar (undefined döndürür).
vi.restoreAllMocks
Tüm spy'larda .mockRestore() çağrısı yapar. Bu, mock geçmişini temizler ve uygulamasını orijinal olana sıfırlar.
vi.spyOn
- Tür:
<T, K extends keyof T>(object: T, method: K, accessType?: 'get' | 'set') => MockInstance
vi.fn() benzer şekilde bir nesnenin bir yöntemi veya getter/setter'ı üzerinde bir spy oluşturur. Bir mock fonksiyonu döndürür.
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
Tüm yöntemleri orijinal uygulamalarına geri yüklemek için afterEach içinde vi.restoreAllMocks çağırabilirsiniz (veya test.restoreMocks etkinleştirebilirsiniz). Bu, orijinal nesne tanımlayıcısını geri yükler; bu nedenle, yöntemin uygulamasını değiştiremezsiniz:
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!TIP
Tarayıcı Modunda dışa aktarılan yöntemleri casuslamak mümkün değildir. Bunun yerine, vi.mock("./file-path.js", { spy: true }) çağırarak her dışa aktarılan yöntemi casuslayabilirsiniz. Bu, her dışa aktarmayı mock eder ancak uygulamasını sağlam tutar, yöntemin doğru şekilde çağrılıp çağrılmadığını doğrulamanıza olanak tanır.
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);Ve jsdom veya diğer Node.js ortamlarında dışa aktarmaları casuslamak mümkün olsa da, bu gelecekte değişebilir.
vi.stubEnv
- Tür:
<T extends string>(name: T, value: T extends "PROD" | "DEV" | "SSR" ? boolean : string | undefined) => Vitest
process.env ve import.meta.env üzerindeki çevresel değişkenin değerini değiştirir. Değerini vi.unstubAllEnvs çağırarak geri yükleyebilirsiniz.
import { vi } from 'vitest';
// `process.env.NODE_ENV` ve `import.meta.env.NODE_ENV`
// "vi.stubEnv" çağrılmadan önce "development"
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;
// diğer env'leri değiştirmez
import.meta.env.MODE === 'development';TIP
Değeri basitçe atayarak da değiştirebilirsiniz, ancak önceki değeri geri yüklemek için vi.unstubAllEnvs kullanamazsınız:
import.meta.env.MODE = 'test';vi.unstubAllEnvs
- Tür:
() => Vitest
vi.stubEnv ile değiştirilen tüm import.meta.env ve process.env değerlerini geri yükler. İlk kez çağrıldığında, Vitest orijinal değeri hatırlar ve unstubAllEnvs tekrar çağrılana kadar saklar.
import { vi } from 'vitest';
// `process.env.NODE_ENV` ve `import.meta.env.NODE_ENV`
// stubEnv çağrılmadan önce "development"
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();
// ilk "stubEnv" çağrısından önce saklanan değere geri yükler
process.env.NODE_ENV === 'development';
import.meta.env.NODE_ENV === 'development';vi.stubGlobal
- Tür:
(name: string | number | symbol, value: unknown) => Vitest
Global değişkenin değerini değiştirir. Orijinal değerini vi.unstubAllGlobals çağırarak geri yükleyebilirsiniz.
import { vi } from 'vitest';
// `innerWidth` stubGlobal çağrılmadan önce "0"
vi.stubGlobal('innerWidth', 100);
innerWidth === 100;
globalThis.innerWidth === 100;
// jsdom veya happy-dom kullanıyorsanız
window.innerWidth === 100;TIP
Değeri basitçe globalThis veya window'a (eğer jsdom veya happy-dom ortamı kullanıyorsanız) atayarak da değiştirebilirsiniz, ancak orijinal değeri geri yüklemek için vi.unstubAllGlobals kullanamazsınız:
globalThis.innerWidth = 100;
// jsdom veya happy-dom kullanıyorsanız
window.innerWidth = 100;vi.unstubAllGlobals
- Tür:
() => Vitest
vi.stubGlobal ile değiştirilen globalThis/global (ve window/top/self/parent, eğer jsdom veya happy-dom ortamı kullanıyorsanız) üzerindeki tüm global değerleri geri yükler. İlk kez çağrıldığında, Vitest orijinal değeri hatırlar ve unstubAllGlobals tekrar çağrılana kadar saklar.
import { vi } from 'vitest';
const Mock = vi.fn();
// IntersectionObserver "stubGlobal" çağrılmadan önce "undefined"
vi.stubGlobal('IntersectionObserver', Mock);
IntersectionObserver === Mock;
global.IntersectionObserver === Mock;
globalThis.IntersectionObserver === Mock;
// jsdom veya happy-dom kullanıyorsanız
window.IntersectionObserver === Mock;
vi.unstubAllGlobals();
globalThis.IntersectionObserver === undefined;
'IntersectionObserver' in globalThis === false;
// tanımlı olmadığı için ReferenceError fırlatır
IntersectionObserver === undefined;Sahte Zamanlayıcılar
Bu bölüm, sahte zamanlayıcılarla nasıl çalışılacağını açıklar.
vi.advanceTimersByTime
- Tür:
(ms: number) => Vitest
Bu yöntem, belirtilen milisaniye sayısı geçene veya kuyruk boşalana kadar (hangisi önce gelirse) başlatılan her zamanlayıcıyı çağırır.
let i = 0;
setInterval(() => console.log(++i), 50);
vi.advanceTimersByTime(150);
// log: 1
// log: 2
// log: 3vi.advanceTimersByTimeAsync
- Tür:
(ms: number) => Promise<Vitest>
Bu yöntem, belirtilen milisaniye sayısı geçene veya kuyruk boşalana kadar (hangisi önce gelirse) başlatılan her zamanlayıcıyı çağırır. Bu, asenkron olarak ayarlanmış zamanlayıcıları içerir.
let i = 0;
setInterval(() => Promise.resolve().then(() => console.log(++i)), 50);
await vi.advanceTimersByTimeAsync(150);
// log: 1
// log: 2
// log: 3vi.advanceTimersToNextTimer
- Tür:
() => Vitest
Bir sonraki kullanılabilir zamanlayıcıyı çağırır. Her zamanlayıcı çağrısı arasında doğrulama yapmak için kullanışlıdır. Zamanlayıcıları kendiniz yönetmek için zincirleme çağrı yapabilirsiniz.
let i = 0;
setInterval(() => console.log(++i), 50);
vi.advanceTimersToNextTimer() // log: 1
.advanceTimersToNextTimer() // log: 2
.advanceTimersToNextTimer(); // log: 3vi.advanceTimersToNextTimerAsync
- Tür:
() => Promise<Vitest>
Bir sonraki kullanılabilir zamanlayıcıyı çağıracak ve asenkron olarak ayarlanmışsa çözülene kadar bekler. Her zamanlayıcı çağrısı arasında doğrulama yapmak için kullanışlıdır.
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: 3vi.advanceTimersToNextFrame 2.1.0+
- Tür:
() => Vitest
vi.advanceTimersByTime benzer, ancak requestAnimationFrame ile şu anda zamanlanmış geri çağırmaları yürütmek için gereken milisaniye kadar zamanlayıcıları ilerletir.
let frameRendered = false;
requestAnimationFrame(() => {
frameRendered = true;
});
vi.advanceTimersToNextFrame();
expect(frameRendered).toBe(true);vi.getTimerCount
- Tür:
() => number
Bekleyen zamanlayıcı sayısını alır.
vi.clearAllTimers
Çalışması planlanan tüm zamanlayıcıları kaldırır. Bu zamanlayıcılar gelecekte asla çalışmaz.
vi.getMockedSystemTime
- Tür:
() => Date | null
setSystemTime kullanılarak ayarlanan mock edilmiş geçerli tarihi döndürür. Tarih mock edilmemişse yöntem null döndürecektir.
vi.getRealSystemTime
- Tür:
() => number
vi.useFakeTimers kullanırken, Date.now çağrıları mock edilir. Gerçek zamanı milisaniye cinsinden almanız gerekiyorsa, bu fonksiyonu çağırabilirsiniz.
vi.runAllTicks
- Tür:
() => Vitest
process.nextTick tarafından kuyruğa alınan her mikro görevi çağırır. Bu, kendi kendine zamanlanmış tüm mikro görevleri de çalıştırır.
vi.runAllTimers
- Tür:
() => Vitest
Bu yöntem, zamanlayıcı kuyruğu boşalana kadar başlatılan her zamanlayıcıyı çağırır. Bu, runAllTimers sırasında çağrılan her zamanlayıcının ateşleneceği anlamına gelir. Sonsuz bir aralığınız varsa, 10.000 denemeden sonra hata fırlatır (fakeTimers.loopLimit ile yapılandırılabilir).
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: 3vi.runAllTimersAsync
- Tür:
() => Promise<Vitest>
Bu yöntem, zamanlayıcı kuyruğu boşalana kadar başlatılan her zamanlayıcıyı asenkron olarak çağırır. Bu, runAllTimersAsync sırasında çağrılan her zamanlayıcının, hatta asenkron zamanlayıcıların bile ateşleneceği anlamına gelir. Sonsuz bir aralığınız varsa, 10.000 denemeden sonra hata fırlatır (fakeTimers.loopLimit ile yapılandırılabilir).
setTimeout(async () => {
console.log(await Promise.resolve('result'));
}, 100);
await vi.runAllTimersAsync();
// log: resultvi.runOnlyPendingTimers
- Tür:
() => Vitest
Bu yöntem, vi.useFakeTimers çağrısından sonra başlatılan her zamanlayıcıyı çağırır. Çağrısı sırasında başlatılan hiçbir zamanlayıcıyı ateşlemez.
let i = 0;
setInterval(() => console.log(++i), 50);
vi.runOnlyPendingTimers();
// log: 1vi.runOnlyPendingTimersAsync
- Tür:
() => Promise<Vitest>
Bu yöntem, vi.useFakeTimers çağrısından sonra başlatılan her zamanlayıcıyı, hatta asenkron olanları bile asenkron olarak çağırır. Çağrısı sırasında başlatılan hiçbir zamanlayıcıyı ateşlemez.
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: 1vi.setSystemTime
- Tür:
(date: string | number | Date) => void
Sahte zamanlayıcılar etkinleştirilmişse, bu yöntem kullanıcının sistem saatini değiştirmesini simüle eder (hrtime, performance.now veya new Date() gibi tarihle ilgili API'leri etkiler) - ancak hiçbir zamanlayıcıyı ateşlemez. Sahte zamanlayıcılar etkinleştirilmemişse, bu yöntem yalnızca Date.* çağrılarını mock eder.
Geçerli tarihe bağlı herhangi bir şeyi test etmeniz gerekiyorsa kullanışlıdır - örneğin kodunuzdaki Luxon çağrıları.
Date ile aynı dize ve sayı argümanlarını kabul eder.
const date = new Date(1998, 11, 19);
vi.useFakeTimers();
vi.setSystemTime(date);
expect(Date.now()).toBe(date.valueOf());
vi.useRealTimers();vi.useFakeTimers
- Tür:
(config?: FakeTimerInstallOpts) => Vitest
Zamanlayıcıları mock etmeyi etkinleştirmek için bu yöntemi çağırmanız gerekir. Bu, vi.useRealTimers() çağrılana kadar zamanlayıcılara (örneğin setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, clearImmediate ve Date) yapılan tüm sonraki çağrıları sarar.
--pool=forks kullanarak Vitest'i node:child_process içinde çalıştırırken nextTick'i mock etmek desteklenmez. NodeJS, node:child_process içinde dahili olarak process.nextTick kullanır ve mock edildiğinde takılır. nextTick'i mock etmek, Vitest'i --pool=threads ile çalıştırırken desteklenir.
Uygulama dahili olarak @sinonjs/fake-timers üzerine kuruludur.
TIP
vi.useFakeTimers() otomatik olarak process.nextTick'i mock etmez. Ancak, toFake argümanında seçeneği belirterek bunu etkinleştirebilirsiniz: vi.useFakeTimers({ toFake: ['nextTick'] }).
vi.isFakeTimers
- Tür:
() => boolean
Sahte zamanlayıcılar etkinleştirilmişse true döndürür.
vi.useRealTimers
- Tür:
() => Vitest
Zamanlayıcılar bittiğinde, mock edilmiş zamanlayıcıları orijinal uygulamalarına döndürmek için bu yöntemi çağırabilirsiniz. Daha önce zamanlanmış tüm zamanlayıcılar atılır.
Çeşitli
Vitest'in sağladığı bir dizi kullanışlı yardımcı fonksiyon.
vi.waitFor
- Tür:
<T>(callback: WaitForCallback<T>, options?: number | WaitForOptions) => Promise<T>
Geri çağırmanın başarıyla yürütülmesini bekler. Geri çağırma bir hata fırlatırsa veya reddedilmiş bir söz döndürürse, başarılı olana veya zaman aşımına uğrayana kadar beklemeye devam eder.
Bu, bazı asenkron eylemlerin tamamlanmasını beklemeniz gerektiğinde çok kullanışlıdır, örneğin bir sunucu başlattığınızda ve başlamasını beklemeniz gerektiğinde.
import { expect, test, vi } from 'vitest';
import { createServer } from './server.js';
test('Sunucu başarıyla başlatıldı', async () => {
const server = createServer();
await vi.waitFor(
() => {
if (!server.isReady) {
throw new Error('Sunucu başlatılmadı');
}
console.log('Sunucu başlatıldı');
},
{
timeout: 500, // varsayılan 1000
interval: 20, // varsayılan 50
}
);
expect(server.isReady).toBe(true);
});Asenkron geri çağırmalar için de çalışır
// @vitest-environment jsdom
import { expect, test, vi } from 'vitest';
import { getDOMElementAsync, populateDOMAsync } from './dom.js';
test('Öğe DOM\'da mevcut', async () => {
// DOM'u doldurmaya başla
populateDOMAsync();
const element = await vi.waitFor(
async () => {
// öğe mevcut olana kadar almaya çalış
const element = (await getDOMElementAsync()) as HTMLElement | null;
expect(element).toBeTruthy();
expect(element.dataset.initialized).toBeTruthy();
return element;
},
{
timeout: 500, // varsayılan 1000
interval: 20, // varsayılan 50
}
);
expect(element).toBeInstanceOf(HTMLElement);
});vi.useFakeTimers kullanılırsa, vi.waitFor her kontrol geri çağırmasında otomatik olarak vi.advanceTimersByTime(interval) çağrısı yapar.
vi.waitUntil
- Tür:
<T>(callback: WaitUntilCallback<T>, options?: number | WaitUntilOptions) => Promise<T>
Bu, vi.waitFor'a benzer, ancak geri çağırma herhangi bir hata fırlatırsa, yürütme hemen kesilir ve bir hata mesajı alınır. Geri çağırma yanlış bir değer döndürürse, doğru bir değer döndürülene kadar bir sonraki kontrol devam eder. Bu, bir şeyin var olmasını beklemeniz gerektiğinde kullanışlıdır.
Aşağıdaki örneğe bakın. Öğenin sayfada görünmesini beklemek için vi.waitUntil kullanabiliriz ve ardından öğeyle bir şeyler yapabiliriz.
import { expect, test, vi } from 'vitest';
test('Öğe doğru şekilde render edildi', async () => {
const element = await vi.waitUntil(() => document.querySelector('.element'), {
timeout: 500, // varsayılan 1000
interval: 20, // varsayılan 50
});
// öğeyle bir şeyler yap
expect(element.querySelector('.element-child')).toBeTruthy();
});vi.hoisted
- Tür:
<T>(factory: () => T) => T
ES modüllerindeki tüm statik import ifadeleri dosyanın en üstüne yükseltilir, bu nedenle içe aktarmalardan önce tanımlanan herhangi bir kod aslında içe aktarmalar değerlendirildikten sonra yürütülür.
Ancak, bir modülü içe aktarmadan önce tarihleri mock etmek gibi bazı yan etkileri çağırmak faydalı olabilir.
Bu sınırlamayı aşmak için, statik içe aktarmaları dinamik olanlara şu şekilde yeniden yazabilirsiniz:
callFunctionWithSideEffect()
- import { value } from './some/module.js'
+ const { value } = await import('./some/module.js')vitest çalıştırırken, vi.hoisted yöntemini kullanarak bunu otomatik olarak yapabilirsiniz.
- callFunctionWithSideEffect()
import { value } from './some/module.js'
+ vi.hoisted(() => callFunctionWithSideEffect())Bu yöntem, factory'den döndürülen değeri döndürür. Yerel olarak tanımlanmış değişkenlere kolay erişiminiz gerekiyorsa, bu değeri vi.mock factory'lerinizde kullanabilirsiniz:
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);Bu yöntemin, ortamınız üst düzey await'i desteklemese bile asenkron olarak da çağrılabileceğini akılda tutun:
const promised = await vi.hoisted(async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
return response.json();
});vi.setConfig
- Tür:
RuntimeConfig
Geçerli test dosyası için yapılandırmayı günceller. Bu yöntem yalnızca geçerli test dosyasını etkileyecek yapılandırma seçeneklerini destekler:
vi.setConfig({
allowOnly: true,
testTimeout: 10_000,
hookTimeout: 10_000,
clearMocks: true,
restoreMocks: true,
fakeTimers: {
now: new Date(2021, 11, 19),
// tüm nesneyi destekler
},
maxConcurrency: 10,
sequence: {
hooks: 'stack',
// yalnızca "sequence.hooks" destekler
},
});vi.resetConfig
- Tür:
RuntimeConfig
Daha önce vi.setConfig çağrıldıysa, bu yapılandırmayı orijinal durumuna sıfırlar.