Mocking
Test yazarken, dahili veya harici bir servisin "taklit" bir versiyonunu oluşturmanız sıkça karşılaşılan bir durumdur. Bu işleme genellikle mocking denir. Vitest, vi yardımcısı aracılığıyla size kolaylık sağlayan fonksiyonlar sunar. Bu fonksiyonları import { vi } from 'vitest'
ile içe aktarabilir veya genel olarak (genel yapılandırma etkinleştirildiğinde) erişebilirsiniz.
WARNING
Mock durum değişikliklerini test çalıştırmaları arasında geri almak için, her test çalıştırmasından önce veya sonra mock'ları temizlemeyi veya geri yüklemeyi her zaman unutmayın! Daha fazla bilgi için mockReset
belgelerine bakın.
Hemen başlamak isterseniz, API bölümüne göz atın; aksi takdirde mocking dünyasına daha derinlemesine dalmak için okumaya devam edin.
Tarihler
Bazen test yaparken tutarlılığı sağlamak için tarihi kontrol etmeniz gerekir. Vitest, zamanlayıcıları ve sistem tarihini manipüle etmek için @sinonjs/fake-timers
paketini kullanır. Belirli API hakkında daha fazla bilgiyi burada bulabilirsiniz.
Örnek
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
const businessHours = [9, 17];
function purchase() {
const currentHour = new Date().getHours();
const [open, close] = businessHours;
if (currentHour > open && currentHour < close) {
return { message: 'Success' };
}
return { message: 'Error' };
}
describe('purchasing flow', () => {
beforeEach(() => {
// Vitest'e mock zaman kullandığımızı belirt
vi.useFakeTimers();
});
afterEach(() => {
// Her test çalıştırmasından sonra tarihi geri yükle
vi.useRealTimers();
});
it('allows purchases within business hours', () => {
// İş saatleri içinde saati ayarla
const date = new Date(2000, 1, 1, 13);
vi.setSystemTime(date);
// Date.now() çağrısı yukarıda ayarlanan tarihi döndürecektir
expect(purchase()).toEqual({ message: 'Success' });
});
it('disallows purchases outside of business hours', () => {
// İş saatleri dışında saati ayarla
const date = new Date(2000, 1, 1, 19);
vi.setSystemTime(date);
// Date.now() çağrısı yukarıda ayarlanan tarihi döndürecektir
expect(purchase()).toEqual({ message: 'Error' });
});
});
Fonksiyonlar
Fonksiyonları mocking iki farklı kategoriye ayrılabilir: spying ve mocking.
Bazen belirli bir fonksiyonun çağrılıp çağrılmadığını veya hangi argümanların geçtiğini doğrulamak yeterlidir. Bu durumlarda, doğrudan vi.spyOn()
ile kullanabileceğiniz bir spy yeterli olacaktır (daha fazlasını buradan okuyun).
Ancak spy'lar yalnızca fonksiyonları gözetlemenize yardımcı olabilir, bu fonksiyonların uygulamasını değiştiremezler. Bir fonksiyonun taklit (veya mock) bir versiyonunu oluşturmamız gereken durumlarda vi.fn()
kullanabiliriz (daha fazlasını buradan okuyun).
Fonksiyonları mocking için temel olarak Tinyspy kullanıyoruz, ancak jest
uyumlu hale getirmek için kendi sarmalayıcımız var. Hem vi.fn()
hem de vi.spyOn()
aynı yöntemleri paylaşır, ancak yalnızca vi.fn()
'nin döndürdüğü sonuç çağrılabilir.
Örnek
import { afterEach, describe, expect, it, vi } from 'vitest';
const messages = {
items: [
{ message: 'Simple test message', from: 'Testman' },
// ...
],
getLatest, // (destekleniyorsa bir getter veya setter da olabilir)
};
function getLatest(index = messages.items.length - 1) {
return messages.items[index];
}
describe('reading messages', () => {
afterEach(() => {
vi.restoreAllMocks();
});
it('should get the latest message with a spy', () => {
const spy = vi.spyOn(messages, 'getLatest');
expect(spy.getMockName()).toEqual('getLatest');
expect(messages.getLatest()).toEqual(
messages.items[messages.items.length - 1]
);
expect(spy).toHaveBeenCalledTimes(1);
spy.mockImplementationOnce(() => 'access-restricted');
expect(messages.getLatest()).toEqual('access-restricted');
expect(spy).toHaveBeenCalledTimes(2);
});
it('should get with a mock', () => {
const mock = vi.fn().mockImplementation(getLatest);
expect(mock()).toEqual(messages.items[messages.items.length - 1]);
expect(mock).toHaveBeenCalledTimes(1);
mock.mockImplementationOnce(() => 'access-restricted');
expect(mock()).toEqual('access-restricted');
expect(mock).toHaveBeenCalledTimes(2);
expect(mock()).toEqual(messages.items[messages.items.length - 1]);
expect(mock).toHaveBeenCalledTimes(3);
});
});
Daha Fazla
Globals
jsdom
veya node
ile bulunmayan global değişkenleri vi.stubGlobal
yardımcısını kullanarak taklit edebilirsiniz. Bu, global değişkenin değerini bir globalThis
nesnesine atayacaktır.
import { vi } from 'vitest';
const IntersectionObserverMock = vi.fn(() => ({
disconnect: vi.fn(),
observe: vi.fn(),
takeRecords: vi.fn(),
unobserve: vi.fn(),
}));
vi.stubGlobal('IntersectionObserver', IntersectionObserverMock);
// şimdi buna `IntersectionObserver` veya `window.IntersectionObserver` olarak erişebilirsiniz
Modüller
Mock modüller, başka bir kodda çağrılan üçüncü taraf kütüphaneleri gözlemlemenize, argümanları ve çıktıyı test etmenize ve hatta uygulamasını yeniden tanımlamanıza olanak tanır.
Daha ayrıntılı bir API açıklaması için vi.mock()
API bölümüne bakın.
Otomatik Mocking Algoritması
Kodunuz, ilişkili bir __mocks__
dosyası veya bu modül için bir factory
olmadan bir modülü içe aktarıyorsa, Vitest modülün kendisini çağırarak ve her dışa aktarmayı taklit ederek otomatik olarak mocking yapacaktır.
Aşağıdaki prensipler geçerlidir:
- Tüm diziler boşaltılacaktır.
- Tüm ilkel tipler ve koleksiyonlar aynı kalacaktır.
- Tüm nesneler derin kopyalanacaktır.
- Sınıfların ve prototiplerinin tüm örnekleri derin kopyalanacaktır.
Sanal Modüller
Vitest, Vite sanal modüllerini mocking'i destekler. Jest'te sanal modüllerin işlenişinden farklı çalışır. virtual: true
'yu bir vi.mock
fonksiyonuna geçirmek yerine, modülün var olduğunu Vite'a söylemeniz gerekir, aksi takdirde ayrıştırma sırasında başarısız olur. Bunu birkaç şekilde yapabilirsiniz:
- Bir takma ad sağlayın
// vitest.config.js
export default {
test: {
alias: {
'$app/forms': resolve('./mocks/forms.js'),
},
},
};
- Sanal bir modülü çözen bir eklenti sağlayın
// vitest.config.js
export default {
plugins: [
{
name: 'virtual-modules',
resolveId(id) {
if (id === '$app/forms') {
return 'virtual:$app/forms';
}
},
},
],
};
İkinci yaklaşımın faydası, dinamik olarak farklı sanal giriş noktaları oluşturabilmenizdir. Birkaç sanal modülü tek bir dosyaya yönlendirirseniz, vi.mock
hepsi üzerinde etkili olacaktır, bu nedenle benzersiz tanımlayıcılar kullandığınızdan emin olun.
Mocking Tuzakları
Aynı dosyanın diğer yöntemleri içinde çağrılan yöntemlere yapılan çağrıları taklit etmenin mümkün olmadığını unutmayın. Örneğin, bu kodda:
export function foo() {
return 'foo';
}
export function foobar() {
return `${foo()}bar`;
}
foo
yöntemi doğrudan referans alındığı için dışarıdan taklit etmek mümkün değildir. Bu nedenle bu kod, foobar
içindeki foo
çağrısı üzerinde hiçbir etkisi olmayacaktır (ancak diğer modüllerdeki foo
çağrısını etkileyecektir):
import { vi } from 'vitest';
import * as mod from './foobar.js';
// bu sadece orijinal modülün dışındaki "foo"yu etkileyecektir
vi.spyOn(mod, 'foo');
vi.mock('./foobar.js', async importOriginal => {
return {
...(await importOriginal<typeof import('./foobar.js')>()),
// bu sadece orijinal modülün dışındaki "foo"yu etkileyecektir
foo: () => 'mocked',
};
});
Bu davranışı, foobar
yöntemine doğrudan uygulama sağlayarak doğrulayabilirsiniz:
// foobar.test.js
import * as mod from './foobar.js';
vi.spyOn(mod, 'foo');
// dışa aktarılan foo mock yöntemi referans alır
mod.foobar(mod.foo);
// foobar.js
export function foo() {
return 'foo';
}
export function foobar(injectedFoo) {
return injectedFoo === foo; // false
}
Bu beklenen davranıştır. Mocking'in bu şekilde kullanılması genellikle kötü kodun bir işaretidir. Kodunuzu birden fazla dosyaya yeniden düzenlemeyi veya bağımlılık enjeksiyonu (dependency injection) gibi teknikleri kullanarak uygulama mimarinizi iyileştirmeyi düşünün.
Örnek
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { Client } from 'pg';
import { failure, success } from './handlers.js';
// yapılacakları al
export async function getTodos(event, context) {
const client = new Client({
// ...clientOptions
});
await client.connect();
try {
const result = await client.query('SELECT * FROM todos;');
client.end();
return success({
message: `${result.rowCount} item(s) returned`,
data: result.rows,
status: true,
});
} catch (e) {
console.error(e.stack);
client.end();
return failure({ message: e, status: false });
}
}
vi.mock('pg', () => {
const Client = vi.fn();
Client.prototype.connect = vi.fn();
Client.prototype.query = vi.fn();
Client.prototype.end = vi.fn();
return { Client };
});
vi.mock('./handlers.js', () => {
return {
success: vi.fn(),
failure: vi.fn(),
};
});
describe('get a list of todo items', () => {
let client;
beforeEach(() => {
client = new Client();
});
afterEach(() => {
vi.clearAllMocks();
});
it('should return items successfully', async () => {
client.query.mockResolvedValueOnce({ rows: [], rowCount: 0 });
await getTodos();
expect(client.connect).toBeCalledTimes(1);
expect(client.query).toBeCalledWith('SELECT * FROM todos;');
expect(client.end).toBeCalledTimes(1);
expect(success).toBeCalledWith({
message: '0 item(s) returned',
data: [],
status: true,
});
});
it('should throw an error', async () => {
const mError = new Error('Unable to retrieve rows');
client.query.mockRejectedValueOnce(mError);
await getTodos();
expect(client.connect).toBeCalledTimes(1);
expect(client.query).toBeCalledWith('SELECT * FROM todos;');
expect(client.end).toBeCalledTimes(1);
expect(failure).toBeCalledWith({ message: mError, status: false });
});
});
Dosya Sistemi
Dosya sistemini taklit etmek, testlerin gerçek dosya sistemine bağlı olmamasını sağlayarak testleri daha güvenilir ve öngörülebilir hale getirir. Bu yalıtım sayesinde, önceki testlerin yan etkileri önlenir. İzin sorunları, disk dolu senaryoları veya okuma/yazma hataları gibi gerçek bir dosya sistemiyle çoğaltılması zor veya imkansız olabilecek hata koşullarını ve uç durumları test etmeye olanak tanır.
Vitest, kutudan çıktığı gibi herhangi bir dosya sistemi mocking API'si sağlamaz. fs
modülünü manuel olarak taklit etmek için vi.mock
kullanabilirsiniz, ancak bakımı zordur. Bunun yerine, bunu sizin için yapması için memfs
kullanmanızı öneririz. memfs
, gerçek diske dokunmadan dosya sistemi işlemlerini simüle eden bellek içi bir dosya sistemi oluşturur. Bu yaklaşım hızlı ve güvenlidir, gerçek dosya sistemine olası yan etkileri önler.
Örnek
Her fs
çağrısını otomatik olarak memfs
'e yönlendirmek için projenizin kökünde __mocks__/fs.cjs
ve __mocks__/fs/promises.cjs
dosyalarını oluşturabilirsiniz:
// `import` da kullanabiliriz, ancak o zaman
// her dışa aktarma açıkça tanımlanmalı
const { fs } = require('memfs');
module.exports = fs;
// `import` da kullanabiliriz, ancak o zaman
// her dışa aktarma açıkça tanımlanmalı
const { fs } = require('memfs');
module.exports = fs.promises;
// read-hello-world.js
import { readFileSync } from 'node:fs';
export function readHelloWorld(path) {
return readFileSync(path);
}
// hello-world.test.js
import { beforeEach, expect, it, vi } from 'vitest';
import { fs, vol } from 'memfs';
import { readHelloWorld } from './read-hello-world.js';
// Vitest'e __mocks__ klasöründen fs mock'unu kullanmasını söyle
// fs her zaman mocklanacaksa bu bir kurulum dosyasında yapılabilir
vi.mock('node:fs');
vi.mock('node:fs/promises');
beforeEach(() => {
// bellek içi fs'nin durumunu sıfırla
vol.reset();
});
it('should return correct text', () => {
const path = '/hello-world.txt';
fs.writeFileSync(path, 'hello world');
const text = readHelloWorld(path);
expect(text).toBe('hello world');
});
it('can return a value multiple times', () => {
// birkaç dosya tanımlamak için vol.fromJSON kullanabilirsiniz
vol.fromJSON(
{
'./dir1/hw.txt': 'hello dir1',
'./dir2/hw.txt': 'hello dir2',
},
// varsayılan cwd
'/tmp'
);
expect(readHelloWorld('/tmp/dir1/hw.txt')).toBe('hello dir1');
expect(readHelloWorld('/tmp/dir2/hw.txt')).toBe('hello dir2');
});
İstekler
Vitest Node'da çalıştığı için ağ isteklerini taklit etmek zordur; web API'leri mevcut değildir, bu nedenle bizim için ağ davranışını taklit edecek bir şeye ihtiyacımız var. Bunu başarmak için Mock Service Worker kullanmanızı öneririz. Hem REST
hem de GraphQL
ağ isteklerini taklit etmenize olanak tanır ve çerçeve bağımsızdır.
Mock Service Worker (MSW), testlerinizin yaptığı istekleri yakalayarak çalışır ve uygulama kodunuzu değiştirmeden kullanmanıza olanak tanır. Tarayıcıda bu, Service Worker API'sini kullanır. Node.js'de ve Vitest için @mswjs/interceptors
kütüphanesini kullanır. MSW hakkında daha fazla bilgi edinmek için girişlerini okuyun.
Yapılandırma
Kurulum dosyanızda aşağıdaki gibi kullanabilirsiniz:
import { afterAll, afterEach, beforeAll } from 'vitest';
import { setupServer } from 'msw/node';
import { graphql, http, HttpResponse } from 'msw';
const posts = [
{
userId: 1,
id: 1,
title: 'first post title',
body: 'first post body',
},
// ...
];
export const restHandlers = [
http.get('https://rest-endpoint.example/path/to/posts', () => {
return HttpResponse.json(posts);
}),
];
const graphqlHandlers = [
graphql.query('ListPosts', () => {
return HttpResponse.json({
data: { posts },
});
}),
];
const server = setupServer(...restHandlers, ...graphqlHandlers);
// Tüm testlerden önce sunucuyu başlat
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
// Tüm testlerden sonra sunucuyu kapat
afterAll(() => server.close());
// Her testten sonra işleyicileri sıfırla `test izolasyonu açısından önemli`
afterEach(() => server.resetHandlers());
Sunucuyu
onUnhandleRequest: 'error'
ile yapılandırmak, karşılık gelen bir istek işleyicisi olmayan bir istek geldiğinde bir hata atılmasını sağlar.
Daha Fazla
MSW hakkında çok daha fazlası var. Çerezlere ve sorgu parametrelerine erişebilir, mock hata yanıtları tanımlayabilir ve çok daha fazlasını yapabilirsiniz! MSW ile yapabileceğiniz her şeyi görmek için belgelerini okuyun.
Zamanlayıcılar
Zaman aşımları veya aralıkları içeren kodu test ettiğimizde, testlerimizin beklemesini veya zaman aşımına uğramasını engellemek için, setTimeout
ve setInterval
çağrılarını taklit eden "sahte" zamanlayıcılar kullanarak testlerimizi hızlandırabiliriz.
Daha ayrıntılı bir API açıklaması için vi.useFakeTimers
API bölümüne bakın.
Örnek
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
function executeAfterTwoHours(func) {
setTimeout(func, 1000 * 60 * 60 * 2); // 2 saat
}
function executeEveryMinute(func) {
setInterval(func, 1000 * 60); // 1 dakika
}
const mock = vi.fn(() => console.log('executed'));
describe('delayed execution', () => {
beforeEach(() => {
vi.useFakeTimers();
});
afterEach(() => {
vi.restoreAllMocks();
});
it('should execute the function', () => {
executeAfterTwoHours(mock);
vi.runAllTimers();
expect(mock).toHaveBeenCalledTimes(1);
});
it('should not execute the function', () => {
executeAfterTwoHours(mock);
// 2ms ilerletmek fonksiyonu tetiklemez
vi.advanceTimersByTime(2);
expect(mock).not.toHaveBeenCalled();
});
it('should execute every minute', () => {
executeEveryMinute(mock);
vi.advanceTimersToNextTimer();
expect(mock).toHaveBeenCalledTimes(1);
vi.advanceTimersToNextTimer();
expect(mock).toHaveBeenCalledTimes(2);
});
});
Sınıflar
Tüm sınıflar aynı zamanda fonksiyonlar olduğu için, tek bir vi.fn
çağrısıyla tüm bir sınıfı taklit edebilirsiniz - bu, doğrudan kullanılabilir. Şu anda Vitest'in new
anahtar kelimesini dikkate almadığını unutmayın, bu nedenle bir fonksiyonun gövdesinde new.target
her zaman undefined
'dır.
class Dog {
name: string;
constructor(name: string) {
this.name = name;
}
static getType(): string {
return 'animal';
}
speak(): string {
return 'bark!';
}
isHungry() {}
feed() {}
}
Bu sınıfı ES5 fonksiyonlarıyla yeniden oluşturabiliriz:
const Dog = vi.fn(function (name) {
this.name = name;
});
// statik yöntemlerin doğrudan fonksiyon üzerinde taklit edildiğini unutmayın,
// sınıfın örneği üzerinde değil
Dog.getType = vi.fn(() => 'mocked animal');
// bir sınıfın her örneğinde "speak" ve "feed" yöntemlerini taklit et
// tüm `new Dog()` örnekleri bu spy'ları devralacaktır
Dog.prototype.speak = vi.fn(() => 'loud bark!');
Dog.prototype.feed = vi.fn();
NE ZAMAN KULLANILIR?
Genel olarak, sınıf başka bir modülden yeniden dışa aktarılıyorsa, bir sınıfı modül fabrikası içinde bu şekilde taklit edersiniz:
import { Dog } from './dog.js';
vi.mock(import('./dog.js'), () => {
const Dog = vi.fn();
Dog.prototype.feed = vi.fn();
// ... diğer mocklar
return { Dog };
});
Bu yöntem, aynı arayüzü kabul eden bir fonksiyona bir sınıf örneği geçirmek için de kullanılabilir:
// ./src/feed.ts
function feed(dog: Dog) {
// ...
}
// ./tests/dog.test.ts
import { expect, test, vi } from 'vitest';
import { feed } from '../src/feed.js';
const Dog = vi.fn();
Dog.prototype.feed = vi.fn();
test('can feed dogs', () => {
const dogMax = new Dog('Max');
feed(dogMax);
expect(dogMax.feed).toHaveBeenCalled();
expect(dogMax.isHungry()).toBe(false);
});
Şimdi, Dog
sınıfının yeni bir örneğini oluşturduğumuzda, speak
yöntemi ( feed
ile birlikte) zaten taklit edilmiştir:
const dog = new Dog('Cooper');
dog.speak(); // loud bark!
// çağrının geçerliliğini kontrol etmek için yerleşik doğrulamaları kullanabilirsiniz
expect(dog.speak).toHaveBeenCalled();
Belirli bir örnek için dönüş değerini yeniden atayabiliriz:
const dog = new Dog('Cooper');
// "vi.mocked" bir tür yardımcısıdır, çünkü
// TypeScript, Dog'un mock bir sınıf olduğunu bilmediği için,
// fonksiyonun bir mock olup olmadığını doğrulamadan herhangi bir fonksiyonu MockInstance<T> türüne sarar
vi.mocked(dog.speak).mockReturnValue('woof woof');
dog.speak(); // woof woof
Özelliği taklit etmek için vi.spyOn(dog, 'name', 'get')
yöntemini kullanabiliriz. Bu, taklit edilen özellik üzerinde spy assertion'ları kullanmayı mümkün kılar:
const dog = new Dog('Cooper');
const nameSpy = vi.spyOn(dog, 'name', 'get').mockReturnValue('Max');
expect(dog.name).toBe('Max');
expect(nameSpy).toHaveBeenCalledTimes(1);
TIP
Aynı yöntemi kullanarak getter ve setter'ları da gözetleyebilirsiniz.
Hızlı Başvuru
INFO
Aşağıdaki örneklerde vi
doğrudan vitest
'ten içe aktarılır. Yapılandırmanızda globals
'ı true
olarak ayarlarsanız, genel olarak da kullanabilirsiniz.
İstiyorum ki…
Dışa aktarılan değişkenleri taklit et
// some-path.js
export const getter = 'variable';
// some-path.test.ts
import * as exports from './some-path.js';
vi.spyOn(exports, 'getter', 'get').mockReturnValue('mocked');
Dışa aktarılan bir fonksiyonu taklit et
vi.mock
ile örnek:
WARNING
Bir vi.mock
çağrısının dosyanın en üstüne (hoisted) taşındığını unutmayın. Her zaman tüm içe aktarmalardan önce yürütülecektir.
// ./some-path.js
export function method() {}
import { method } from './some-path.js';
vi.mock('./some-path.js', () => ({
method: vi.fn(),
}));
vi.spyOn
ile örnek:
import * as exports from './some-path.js';
vi.spyOn(exports, 'method').mockImplementation(() => {});
Dışa aktarılan bir sınıf uygulamasını taklit et
vi.mock
ve.prototype
ile örnek:
// ./some-path.ts
export class SomeClass {}
import { SomeClass } from './some-path.js';
vi.mock(import('./some-path.js'), () => {
const SomeClass = vi.fn();
SomeClass.prototype.someMethod = vi.fn();
return { SomeClass };
});
// SomeClass.mock.instances SomeClass örneklerini içerecektir
vi.spyOn
ile örnek:
import * as mod from './some-path.js';
const SomeClass = vi.fn();
SomeClass.prototype.someMethod = vi.fn();
vi.spyOn(mod, 'SomeClass').mockImplementation(SomeClass);
Bir fonksiyondan dönen bir nesneyi gözetle
- Önbellek kullanarak örnek:
// some-path.ts
export function useObject() {
return { method: () => true };
}
// useObject.js
import { useObject } from './some-path.js';
const obj = useObject();
obj.method();
// useObject.test.js
import { useObject } from './some-path.js';
vi.mock(import('./some-path.js'), () => {
let _cache;
const useObject = () => {
if (!_cache) {
_cache = {
method: vi.fn(),
};
}
// şimdi useObject() her çağrıldığında
// aynı nesne referansını döndürecektir
return _cache;
};
return { useObject };
});
const obj = useObject();
// obj.method some-path içinde çağrıldı
expect(obj.method).toHaveBeenCalled();
Bir modülün bir kısmını taklit et
import { mocked, original } from './some-path.js';
vi.mock(import('./some-path.js'), async importOriginal => {
const mod = await importOriginal();
return {
...mod,
mocked: vi.fn(),
};
});
original(); // orijinal davranışı gösterir
mocked(); // bir spy fonksiyonudur
WARNING
Bunun yalnızca dış erişimi taklit ettiğini unutmayın. Bu örnekte, original
dahili olarak mocked
'ı çağırırsa, her zaman modülde tanımlanan fonksiyonu çağıracaktır, mock fabrikadaki fonksiyonu değil.
Geçerli tarihi taklit et
Date
'in zamanını taklit etmek için vi.setSystemTime
yardımcı fonksiyonunu kullanabilirsiniz. Bu değer farklı testler arasında otomatik olarak sıfırlanmaz.
vi.useFakeTimers
kullanmanın Date
'in zamanını da değiştirdiğini unutmayın.
const mockDate = new Date(2022, 0, 1);
vi.setSystemTime(mockDate);
const now = new Date();
expect(now.valueOf()).toBe(mockDate.valueOf());
// mock zamanı sıfırla
vi.useRealTimers();
Global bir değişkeni taklit et
globalThis
'e bir değer atayarak veya vi.stubGlobal
yardımcısını kullanarak global değişkeni ayarlayabilirsiniz. vi.stubGlobal
kullanırken, unstubGlobals
yapılandırma seçeneğini etkinleştirmediğiniz veya vi.unstubAllGlobals
çağrısı yapmadığınız sürece farklı testler arasında otomatik olarak sıfırlanmaz.
vi.stubGlobal('__VERSION__', '1.0.0');
expect(__VERSION__).toBe('1.0.0');
import.meta.env
'i taklit et
- Ortam değişkenini değiştirmek için, ona yeni bir değer atayabilirsiniz.
WARNING
Ortam değişkeni değeri farklı testler arasında otomatik olarak sıfırlanmaz.
import { beforeEach, expect, it } from 'vitest';
// testler çalıştırılmadan önce "VITE_ENV" değeri "test"tir
const originalViteEnv = import.meta.env.VITE_ENV;
beforeEach(() => {
import.meta.env.VITE_ENV = originalViteEnv;
});
it('changes value', () => {
import.meta.env.VITE_ENV = 'staging';
expect(import.meta.env.VITE_ENV).toBe('staging');
});
- Değeri/değerleri otomatik olarak sıfırlamak isterseniz,
unstubEnvs
yapılandırma seçeneği etkinleştirilmişvi.stubEnv
yardımcısını kullanabilirsiniz (veya birbeforeEach
kancasındavi.unstubAllEnvs
manuel olarak çağırabilirsiniz):
import { expect, it, vi } from 'vitest';
// testler çalıştırılmadan önce "VITE_ENV" değeri "test"tir
import.meta.env.VITE_ENV === 'test';
it('changes value', () => {
vi.stubEnv('VITE_ENV', 'staging');
expect(import.meta.env.VITE_ENV).toBe('staging');
});
it('the value is restored before running an other test', () => {
expect(import.meta.env.VITE_ENV).toBe('test');
});
// vitest.config.ts
export default defineConfig({
test: {
unstubEnvs: true,
},
});