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.js
Bir 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: 3
vi.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: 3
vi.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: 3
vi.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: 3
vi.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: 3
vi.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: result
vi.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: 1
vi.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: 1
vi.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.