Vi
Vitest, vi
yardımcısı ile size yardımcı olacak işlevsel araçlar sağlar. Buna global olarak erişim sağlayabilirsiniz (globals yapılandırması etkinleştirildiğinde) veya doğrudan vitest
ten içe aktarabilirsiniz:
import { vi } from 'vitest';
Mock Modülleri
Bu bölüm, bir modülü taklit ederken kullanabileceğiniz API'yi açıklar. Vitest'in require()
kullanılarak içe aktarılan modülleri taklit etmeyi desteklemediğine dikkat edin.
vi.mock
- Tür:
(path: string, factory?: (importOriginal: () => unknown) => unknown) => void
Sağlanan path
'teki modülü taklit ederek, bu modüle yapılan tüm içe aktarmaları başka bir modülle değiştirir. Bir yol içinde yapılandırılmış Vite takma adlarını kullanabilirsiniz. vi.mock
çağrısı yukarı taşınır (hoisted), bu nedenle onu nerede çağırdığınız önemli değildir. Her zaman tüm içe aktarmalardan önce yürütülecektir. Kapsam dışındaki değişkenlere başvurmanız gerekiyorsa, bunları vi.hoisted
içinde tanımlayıp vi.mock
içinde kullanabilirsiniz.
WARNING
vi.mock
sadece import
anahtar kelimesi ile içe aktarılan modüllerle çalışır, require
ile çalışmaz.
vi.mock
'u yukarı taşımak (hoist) için Vitest, dosyalarınızı statik olarak analiz eder. Bu nedenle, doğrudan vitest
paketinden içe aktarılmayan vi
'nin (örneğin, bazı yardımcı dosyalardan) kullanılamayacağını unutmayın. vitest
ten içe aktarılan vi
ile vi.mock
kullanın veya globals
yapılandırma seçeneğini etkinleştirin.
Vitest, bir kurulum dosyasının içinde içe aktarılan modülleri taklit etmez, çünkü bir test dosyası çalıştırıldığında bunlar önbelleğe alınmış olur. Bir test dosyası çalıştırmadan önce tüm modül önbelleklerini temizlemek için vi.hoisted
içinde vi.resetModules()
çağırabilirsiniz.
WARNING
Tarayıcı modu şu anda modülleri taklit etmeyi desteklememektedir. Bu özelliği GitHub sorununda takip edebilirsiniz.
factory
tanımlanmışsa, tüm içe aktarmalar bu factory'nin sonucunu döndürür. Vitest, factory'yi yalnızca bir kez çağırır ve vi.unmock
veya vi.doUnmock
çağrılana kadar tüm sonraki içe aktarmalar için sonuçları önbelleğe alır.
jest
'ten farklı olarak, factory eşzamansız olabilir. vi.importActual
kullanabilir veya ilk argüman olarak geçirilen factory'ye sahip bir yardımcı kullanabilir ve asıl modülü içeride alabilirsiniz.
import { vi } from 'vitest';
// ---cut---
// JavaScript kullanırken
vi.mock('./path/to/module.js', async importOriginal => {
const mod = await importOriginal();
return {
...mod,
// bazı dışa aktarmaları değiştir
namedExport: vi.fn(),
};
});
// TypeScript kullanırken
vi.mock('./path/to/module.js', async importOriginal => {
const mod = await importOriginal<typeof import('./path/to/module.js')>();
return {
...mod,
// bazı dışa aktarmaları değiştir
namedExport: vi.fn(),
};
});
WARNING
vi.mock
yukarı taşınır (hoisted) (başka bir deyişle, dosyanın en üstüne taşınır). Bu, onu ne zaman yazarsanız yazın (ister beforeEach
içinde ister test
içinde olsun), aslında bundan önce çağrılacağı anlamına gelir.
Bu, factory dışında tanımlanan değişkenleri factory içinde kullanamayacağınız anlamına gelir.
Factory içinde değişkenler kullanmanız gerekiyorsa, vi.doMock
'u deneyin. Aynı şekilde çalışır, ancak yukarı taşınmaz (hoisted). Yalnızca sonraki içe aktarmaları taklit ettiğini unutmayın.
Ayrıca, vi.mock
'tan önce bildirilmişse, vi.hoisted
yöntemi tarafından tanımlanan değişkenlere de 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
Eğer varsayılan dışa aktarmaya sahip bir modülü taklit ediyorsanız, döndürülen factory fonksiyonu nesnesi içinde bir default
anahtarı belirtmelisiniz. Bu, ES modülüne özgü bir uyarıdır; bu nedenle, jest
CommonJS modüllerini kullandığından jest
belgeleri farklılık gösterebilir. Örneğin,
vi.mock('./path/to/module.js', () => {
return {
default: { myDefaultKey: vi.fn() },
namedExport: vi.fn(),
// vb...
};
});
Taklit ettiğiniz bir 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 bulup bunu gerçek bir modül olarak kullanmaya çalışır. Bir bağımlılığı taklit ediyorsanız, Vitest projenin kökünde bir __mocks__
klasörü bulmaya çalışır (varsayılan process.cwd()
'dir). deps.moduleDirectories yapılandırma seçeneği aracılığıyla Vitest'e bağımlılıkların nerede bulunduğunu söyleyebilirsiniz.
Örneğin, şu dosya yapısına sahipsiniz:
- __mocks__
- axios.js
- src
__mocks__
- increment.js
- increment.js
- tests
- increment.test.js
Bir test dosyasında factory sağlanmadan vi.mock
çağırırsanız, modül olarak kullanılacak __mocks__
klasöründe bir dosya bulur:
// increment.test.js
import { vi } from 'vitest';
// axios, `__mocks__/axios.js`'den varsayılan bir dışa aktarımdır
import axios from 'axios';
// increment, `src/__mocks__/increment.js`'den adlandırılmış bir dışa aktarımdır
import { increment } from '../increment.js';
vi.mock('axios');
vi.mock('../increment.js');
axios.get(`/apples/${increment(1)}`);
WARNING
vi.mock
'u çağırmazsanız, modüllerin otomatik olarak taklit edilmediğini unutmayın. Jest'in otomatik taklit davranışını çoğaltmak için, setupFiles
içindeki her gerekli modül için vi.mock
çağırabilirsiniz.
__mocks__
klasörü yoksa veya bir factory belirtilmemişse, Vitest orijinal modülü içe aktarır ve tüm dışa aktarımlarını otomatik olarak taklit eder. Uygulanan kurallar için algoritma bölümüne bakın.
vi.doMock
- Tür:
(path: string, factory?: (importOriginal: () => unknown) => unknown) => void
vi.mock
ile aynıdır, ancak dosyanın en üstüne taşınmaz (hoisted), bu nedenle genel dosya kapsamındaki değişkenlere başvurabilirsiniz. Modülün bir sonraki dinamik içe aktarımı taklit edilecektir.
WARNING
Bu, bundan önce içe aktarılan modülleri taklit etmez. Unutmayın, ESM'deki tüm statik içe aktarmalar her zaman yukarı taşınır (hoisted), bu nedenle bu ifadeyi statik bir içe aktarmadan önce yazmak, onun içe aktarmadan önce çağrılmasını sağlamaz:
vi.doMock('./increment.js'); // bu, içe aktarma ifadesinden _sonra_ çağrılacaktı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 taklit edilmedi, çünkü vi.doMock henüz çağrılmadı
increment(1) === 2;
let mockedIncrement = 100;
beforeEach(() => {
// bir factory içindeki değişkenlere erişebilirsiniz
vi.doMock('./increment.js', () => ({ increment: () => ++mockedIncrement }));
});
test('sonraki modülün içe aktarılması taklit edilen modülü içe aktarır', async () => {
// orijinal içe aktarma TAKLİT 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 taklit edilen 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 tip yardımcısıdır. Sadece geçirilen nesneyi döndürür.
partial
true
olduğunda, bir Partial<T>
dönüş değeri bekleyecektir. Varsayılan olarak, bu yalnızca TypeScript'in ilk düzey değerlerinin taklit edildiğine inanmasını sağlayacaktır. Eğer tüm nesnenin taklit edildiğini TypeScript'e belirtmek isterseniz, ikinci bir argüman olarak { deep: true }
gönderebilirsiniz.
import example from './example.js';
vi.mock('./example.js');
test('1 + 1 eşittir 10', async () => {
vi.mocked(example.calc).mockReturnValue(10);
expect(example.calc(1, '+', 1)).toBe(10);
});
vi.importActual
- Tür:
<T>(path: string) => Promise<T>
Modülü, taklit edilip edilmeyeceğine dair tüm kontrolleri atlayarak içe aktarır. Modülü kısmen taklit etmek istiyorsanız yararlı 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 özellikleri (iç içe geçmiş özellikler dahil) taklit edilmiş 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) => void
Modülü taklit edilen kayıt defterinden kaldırır. Tüm içe aktarma çağrıları, daha önce taklit edilmiş olsa bile orijinal modülü döndürür. Bu çağrı dosyanın en üstüne taşındığı (hoisted) için, sadece setupFiles
içinde tanımlanan modüllerin taklidini kaldırır.
vi.doUnmock
- Tür:
(path: string) => void
vi.unmock
ile aynıdır, ancak dosyanın en üstüne taşınmaz (hoisted). Modülün bir sonraki içe aktarımı taklit edilmiş sürüm yerine orijinal modülü içe aktaracaktır. Bu, daha önce içe aktarılmış modüllerin taklidini kaldırmaz.
// ./increment.js
export function increment(number) {
return number + 1;
}
import { increment } from './increment.js';
// increment zaten taklit edildi, çünkü vi.mock yukarı taşındı (hoisted)
increment(1) === 100;
// bu yukarı taşınır (hoisted) ve factory, 1. satırdaki içe aktarmadan önce çağrılır
vi.mock('./increment.js', () => ({ increment: () => 100 }));
// tüm çağrılar taklit edilir ve `increment` her zaman 100 döndürür
increment(1) === 100;
increment(30) === 100;
// bu yukarı taşınmaz (hoisted), bu nedenle diğer içe aktarma taklidi kaldırılmış 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;
// sonraki içe aktarmanın taklidi kaldırılır, şimdi `increment`, count + 1 döndüren orijinal işlevdir
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üller kayıt defterini sıfırlar. Bu, yeniden içe aktarıldığında modüllerin yeniden değerlendirilmesini sağlar. Üst düzey içe aktarmalar yeniden değerlendirilemez. Bu, yerel durumun testler arasında çakıştığı modülleri izole etmek için faydalı olabilir.
import { vi } from 'vitest';
import { data } from './data.js'; // Her testten önce yeniden değerlendirilmeyecek
beforeEach(() => {
vi.resetModules();
});
test('durumu değiştir', async () => {
const mod = await import('./some/path.js'); // Yeniden değerlendirilecek
mod.changeLocalState('yeni değer');
expect(mod.getLocalState()).toBe('yeni değer');
});
test('modülün eski durumu var', async () => {
const mod = await import('./some/path.js'); // Yeniden değerlendirilecek
expect(mod.getLocalState()).toBe('eski değer');
});
WARNING
Taklit kayıt defterini sıfırlamaz. Taklit kayıt defterini temizlemek için vi.unmock
veya vi.doUnmock
kullanın.
vi.dynamicImportSettled
Tüm dinamik içe aktarmaların yüklenmesini bekleyin. Eğer başka türlü bekleyemeyeceğiniz bir modülü içe aktarmaya başlayan senkron bir çağrınız varsa bu kullanışlıdır.
import { expect, test } from 'vitest';
// Promise döndürülmediği için içe aktarma izlenemiyor
function renderComponent() {
import('./component.js').then(({ render }) => {
render();
});
}
test('işlemler çözümlendi', 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 tümü çözülene kadar bekleyecektir.
Bu yöntem ayrıca, içe aktarma çözüldükten sonraki bir sonraki setTimeout
işaretini de bekleyecektir, böylece tüm eşzamanlı işlemler çözüldüğü zamana kadar tamamlanmış olmalıdır.
İşlevleri ve Nesneleri Taklit Etme
Bu bölüm, yöntem taklitleriyle nasıl çalışılacağını ve çevresel ve genel değişkenlerin nasıl değiştirileceğini açıklar.
vi.fn
- Tür:
(fn?: Function) => Mock
Bir fonksiyon üzerinde bir izleyici (spy) oluşturur, ancak bir fonksiyon olmadan da başlatılabilir. Bir işlev her çağrıldığında, çağrı argümanlarını, dönüşlerini ve örneklerini depolar. Ayrıca, yöntemlerle davranışını değiştirebilirsiniz. Hiçbir işlev verilmezse, taklit çağrıldığında undefined
döndürür.
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
- Tür:
(fn: Function) => boolean
Verilen bir parametrenin bir taklit işlevi olup olmadığını kontrol eder. TypeScript kullanıyorsanız, türünü de daraltacaktır.
vi.clearAllMocks
Tüm izleyicilerde (spies) .mockClear()
çağırır. Bu, taklit geçmişini temizler, ancak uygulamasını varsayılan olana sıfırlamaz.
vi.resetAllMocks
Tüm izleyicilerde (spies) .mockReset()
çağırır. Bu, taklit geçmişini temizler ve uygulamasını boş bir işleve sıfırlar (undefined
döndürür).
vi.restoreAllMocks
Tüm izleyicilerde (spies) .mockRestore()
çağırır. Bu, taklit 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()
'ye benzer olarak, bir nesnenin metodu veya getter/setter'ı üzerinde bir izleyici (spy) oluşturur. Bir taklit işlevi döndürür.
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
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ükleyecektir, 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()); // hala 42!
vi.stubEnv 0.26.0+
- Tür:
(name: string, value: string) => Vitest
process.env
ve import.meta.env
üzerindeki ortam değişkeninin değerini değiştirir. vi.unstubAllEnvs
çağırarak değerini geri yükleyebilirsiniz.
import { vi } from 'vitest';
// `process.env.NODE_ENV` ve `import.meta.env.NODE_ENV`
// "vi.stubEnv" çağrılmadan önce "development"dır
vi.stubEnv('NODE_ENV', 'production');
process.env.NODE_ENV === 'production';
import.meta.env.NODE_ENV === 'production';
// diğer env'leri değiştirmez
import.meta.env.MODE === 'development';
TIP
Değeri basit bir atama ile de değiştirebilirsiniz, ancak önceki değeri geri yüklemek için vi.unstubAllEnvs
kullanamazsınız:
import.meta.env.MODE = 'test';
vi.unstubAllEnvs 0.26.0+
- Tür:
() => Vitest
vi.stubEnv
ile değiştirilmiş olan 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"dır
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 depolanan 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 bir değişkenin değerini değiştirir. vi.unstubAllGlobals
çağırarak değerini geri yükleyebilirsiniz.
import { vi } from 'vitest';
// `innerWidth`, stubGlobal çağrılmadan önce "0"dır
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 0.26.0+
- Tür:
() => Vitest
vi.stubGlobal
ile değiştirilmiş olan globalThis
/global
(ve eğer jsdom
veya happy-dom
ortamı kullanıyorsanız window
/top
/self
/parent
) ü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"dır
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;
// ReferenceError hatası verir, çünkü tanımlanmamıştır
IntersectionObserver === undefined;
Sahte Zamanlayıcılar (Fake Timers)
Bu bölüm, sahte zamanlayıcılarla nasıl çalışılacağını açıklar.
vi.advanceTimersByTime
- Tip:
(ms: number) => Vitest
Bu metot, belirtilen milisaniye sayısı geçene kadar veya zamanlayıcı kuyruğu boşalana kadar başlatılmış olan tüm zamanlayıcıları çalıştırır. Hangisi önce gerçekleşirse o duruma kadar çalışmaya devam eder.
import { vi } from 'vitest';
// ---cut---
let i = 0;
setInterval(() => console.log(++i), 50);
vi.advanceTimersByTime(150);
// log: 1
// log: 2
// log: 3
vi.advanceTimersByTimeAsync
- Tip:
(ms: number) => Promise<Vitest>
Bu metot, belirtilen milisaniye sayısı geçene kadar veya zamanlayıcı kuyruğu boşalana kadar başlatılmış olan tüm zamanlayıcıları çalıştırır. Hangisi önce gerçekleşirse o duruma kadar çalışmaya devam eder. Bu, asenkron olarak ayarlanan zamanlayıcıları da içerir.
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
- Tip:
() => Vitest
Bir sonraki çalışmaya hazır zamanlayıcıyı tetikler. Zamanlayıcı çağrıları arasında doğrulama yapmak için kullanışlıdır. Zamanlayıcıları kendiniz yönetmek için zincirleme şeklinde çağırabilirsiniz.
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
- Tip:
() => Promise<Vitest>
Bir sonraki çalışmaya hazır zamanlayıcıyı tetikler ve eğer asenkron olarak ayarlanmışsa tamamlanmasını bekler. Zamanlayıcı çağrıları arasında doğrulama yapmak için kullanışlıdır.
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
- Tip:
() => number
Bekleyen zamanlayıcıların sayısını döndürür.
vi.clearAllTimers
Çalışması planlanan tüm zamanlayıcıları iptal eder. Bu zamanlayıcılar artık çalıştırılmayacaktır.
vi.getMockedSystemTime
- Tip:
() => Date | null
setSystemTime
kullanılarak ayarlanan taklit edilmiş geçerli tarihi döndürür. Eğer tarih taklit edilmemişse, metot null
döndürür.
vi.getRealSystemTime
- Tip:
() => number
vi.useFakeTimers
kullanılırken, Date.now
çağrıları taklit edilir. Eğer milisaniye cinsinden gerçek zamanı almanız gerekiyorsa, bu fonksiyonu kullanabilirsiniz.
vi.runAllTicks
- Tip:
() => Vitest
process.nextTick
tarafından sıraya alınan her mikro görevi çalıştırır. Bu, kendi kendine planlanmış olan tüm mikro görevleri de çalıştırır.
vi.runAllTimers
- Tip:
() => Vitest
Bu metot, zamanlayıcı kuyruğu boşalana kadar başlatılmış olan tüm zamanlayıcıları çalıştırır. Bu, runAllTimers
sırasında çağrılan tüm zamanlayıcıların tetikleneceği anlamına gelir. Sonsuz bir döngüye girme ihtimaline karşı, 10.000 deneme sonrasında bir hata fırlatılır (fakeTimers.loopLimit
ile yapılandırılabilir).
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
- Tip:
() => Promise<Vitest>
Bu metot, zamanlayıcı kuyruğu boşalana kadar başlatılmış olan tüm zamanlayıcıları asenkron olarak çalıştırır. Bu, runAllTimersAsync
sırasında çağrılan tüm zamanlayıcıların, asenkron zamanlayıcılar olsa bile tetikleneceği anlamına gelir. Sonsuz bir döngüye girme ihtimaline karşı, 10.000 deneme sonrasında bir hata fırlatılır (fakeTimers.loopLimit
ile yapılandırılabilir).
import { vi } from 'vitest';
// ---cut---
setTimeout(async () => {
console.log(await Promise.resolve('result'));
}, 100);
await vi.runAllTimersAsync();
// log: result
vi.runOnlyPendingTimers
- Tip:
() => Vitest
Bu metot, vi.useFakeTimers
çağrısından sonra başlatılan tüm zamanlayıcıları çalıştırır. Bu çağrı sırasında başlatılmış olan hiçbir zamanlayıcıyı tetiklemeyecektir.
import { vi } from 'vitest';
// ---cut---
let i = 0;
setInterval(() => console.log(++i), 50);
vi.runOnlyPendingTimers();
// log: 1
vi.runOnlyPendingTimersAsync
- Tip:
() => Promise<Vitest>
Bu metot, vi.useFakeTimers
çağrısından sonra başlatılan her zamanlayıcıyı, asenkron olanlar bile asenkron olarak çalıştırır. Bu çağrı sırasında başlatılmış olan hiçbir zamanlayıcıyı tetiklemeyecektir.
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
- Tip:
(date: string | number | Date) => void
Eğer sahte zamanlayıcılar etkinleştirilmişse, bu metot sistem saatini değiştirmeyi taklit eder (hrtime
, performance.now
veya new Date()
gibi tarihle ilgili API'leri etkiler) - ancak herhangi bir zamanlayıcıyı tetiklemez. Sahte zamanlayıcılar etkinleştirilmemişse, bu metot yalnızca Date.*
çağrılarını taklit eder.
Mevcut tarihe bağlı herhangi bir şeyi test etmeniz gerekiyorsa kullanışlıdır - örneğin kodunuzun içindeki Luxon çağrıları.
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
- Tip:
(config?: FakeTimerInstallOpts) => Vitest
Zamanlayıcıları taklit etmeyi etkinleştirmek için bu metodu çağırmanız gerekir. 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ı sarmalar.
--pool=forks
kullanılarak node:child_process
içinde Vitest çalıştırılırken nextTick
'i taklit etmek desteklenmez. NodeJS, node:child_process
içinde dahili olarak process.nextTick
kullanır ve taklit edildiğinde askıda kalır. nextTick
'i taklit etmek, Vitest --pool=threads
ile çalıştırılırken desteklenir.
Uygulama dahili olarak @sinonjs/fake-timers
tabanlıdır.
TIP
0.35.0
sürümünden itibaren vi.useFakeTimers()
artık process.nextTick
'i otomatik olarak taklit etmiyor. toFake
argümanında seçeneği belirterek hala taklit edilebilir: vi.useFakeTimers({ toFake: ['nextTick'] })
.
vi.isFakeTimers 0.34.5+
- Tip:
() => boolean
Sahte zamanlayıcılar etkinleştirilmişse true
döndürür.
vi.useRealTimers
- Tip:
() => Vitest
Zamanlayıcılar kullanım dışı bırakıldığında, taklit edilmiş zamanlayıcıları orijinal uygulamalarına döndürmek için bu metodu kullanabilirsiniz. Önceden planlanan tüm zamanlayıcılar iptal edilecektir.
Çeşitli
Vitest'in sağladığı bir dizi kullanışlı yardımcı fonksiyon.
vi.waitFor 0.34.5+
- Tip:
<T>(callback: WaitForCallback<T>, options?: number | WaitForOptions) => Promise<T>
Geri çağırımın başarıyla sonuçlanmasını bekler. Geri çağırım bir hata fırlatırsa veya reddedilen bir promise döndürürse, başarılı olana veya zaman aşımına uğrayana kadar beklemeye devam edecektir.
Bu, bazı asenkron işlemlerin 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);
});
Ayrıca asenkron geri çağırımlar için de çalışır
// @vitest-environment jsdom
import { expect, test, vi } from 'vitest';
import { getDOMElementAsync, populateDOMAsync } from './dom.js';
test('Bir DOM'da öğe var', async () => {
// DOM'u doldurmaya başla
populateDOMAsync();
const element = await vi.waitFor(
async () => {
// var olana kadar öğeyi 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ıyorsa, vi.waitFor
her kontrol geri çağırımında otomatik olarak vi.advanceTimersByTime(interval)
çağırır.
vi.waitUntil 0.34.5+
- Tip:
<T>(callback: WaitUntilCallback<T>, options?: number | WaitUntilOptions) => Promise<T>
Bu, vi.waitFor
'a benzer, ancak geri çağırım herhangi bir hata fırlatırsa, yürütme hemen durur ve bir hata mesajı alınır. Geri çağırım yanlış bir değer döndürürse, bir sonraki kontrol doğru değer döndürülene kadar devam edecektir. Bu, bir sonraki adıma geçmeden önce 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 sonrasında bu öğ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 0.31.0+
- Tip:
<T>(factory: () => T) => T
ES modüllerindeki tüm statik import
ifadeleri dosyanın en üstüne taşınır. Bu nedenle, import'lardan önce tanımlanan herhangi bir kod, aslında import'lar değerlendirildikten sonra yürütülecektir.
Ancak, bir modülü içe aktarmadan önce tarihleri taklit etmek gibi bazı yan etkileri çağırmak yararlı olabilir.
Bu sınırlamayı aşmak için, statik içe aktarmaları aşağıdaki gibi dinamik olanlara yeniden yazabilirsiniz:
callFunctionWithSideEffect()
- import { value } from './some/module.js'
+ const { value } = await import('./some/module.js')
vitest
çalıştırırken, vi.hoisted
metodunu kullanarak bunu otomatik olarak yapabilirsiniz.
- callFunctionWithSideEffect()
import { value } from './some/module.js'
+ vi.hoisted(() => callFunctionWithSideEffect())
Bu metot, factory fonksiyonundan döndürülen değeri döndürür. Eğer yerel olarak tanımlanmış değişkenlere kolayca erişmeniz gerekiyorsa, bu değeri vi.mock
fabrikalarınızda 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);
Ortamınız en üst seviye await'i desteklemese bile bu metodun asenkron olarak da çağrılabileceğini unutmayın:
const promised = await vi.hoisted(async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
return response.json();
});
vi.setConfig
- Tip:
RuntimeConfig
Geçerli test dosyası için yapılandırmayı günceller. Bu metot, yalnızca geçerli test dosyasını etkileyecek olan 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" u destekler
},
});
vi.resetConfig
- Tip:
RuntimeConfig
Daha önce vi.setConfig
çağrıldıysa, bu yapılandırmayı orijinal haline sıfırlayacaktır.