Skip to content
Vitest 0
Main Navigation KılavuzAPIYapılandırmaİleri
1.6.1
0.34.6

Türkçe

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

Türkçe

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

Görünüm

Sidebar Navigation

Kılavuz

Neden Vitest

Başlangıç

Özellikler

Çalışma Alanı

Komut Satırı Arayüzü

Test Filtreleme

Kapsam

Anlık Görüntü (Snapshot) Testleri

Sahtecilik (Mocking)

Tür Testleri

Vitest Arayüzü

Tarayıcı Modu (deneysel)

Kaynak İçi Test

Test Bağlamı

Test Ortamı

Eşleştiricileri Genişletme

IDE Tümleştirmeleri

Hata Ayıklama

Diğer Test Çalıştırıcılarıyla Karşılaştırmalar

Geçiş Rehberi

Yaygın Hatalar

API

Test API Başvurusu

Mock Fonksiyonlar

Vi

expect

expectTypeOf

assertType

Yapılandırma

Vitest'i Yapılandırma

Bu sayfada

Sahtecilik (Mocking) ​

Test yazarken, dahili veya harici bir hizmetin "sahte" bir sürümünü oluşturmanız gerekebilir. Bu işlem genellikle "mocking" (sahtecilik) olarak adlandırılır. Vitest, vi yardımcısı aracılığıyla size bu konuda yardımcı olacak işlevler sunar. import { vi } from 'vitest' ile içe aktarabilir veya küresel yapılandırma etkinleştirildiğinde global olarak erişebilirsiniz.

WARNING

Testler arasındaki sahte durum değişikliklerini önlemek için her testten önce veya sonra sahteleri temizlemeyi veya geri yüklemeyi 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 sahtecilik dünyasına daha derinlemesine dalmak için okumaya devam edin.

Tarihler ​

Bazen test sırasında tutarlılığı sağlamak için tarihin kontrolünü elinizde tutmanız gerekebilir. Vitest, zamanlayıcıları ve sistem tarihini manipüle etmek için @sinonjs/fake-timers paketini kullanır. Belirli API hakkında daha fazla ayrıntıyı burada bulabilirsiniz.

Örnek ​

js
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('satın alma akışı', () => {
  beforeEach(() => {
    // Vitest'e sahte zamanlayıcılar kullanacağımızı belirt
    vi.useFakeTimers();
  });

  afterEach(() => {
    // Her test çalıştırmasından sonra tarihi geri yükle
    vi.useRealTimers();
  });

  it('iş saatleri içinde satın almalara izin verir', () => {
    // İş saatleri içinde saati ayarla
    const date = new Date(2000, 1, 1, 13);
    vi.setSystemTime(date);

    // Date.now()'a erişim yukarıda ayarlanan tarihle sonuçlanacaktır
    expect(purchase()).toEqual({ message: 'Success' });
  });

  it('iş saatleri dışında satın almalara izin vermez', () => {
    // İş saatleri dışında saati ayarla
    const date = new Date(2000, 1, 1, 19);
    vi.setSystemTime(date);

    // Date.now()'a erişim yukarıda ayarlanan tarihle sonuçlanacaktır
    expect(purchase()).toEqual({ message: 'Error' });
  });
});

Fonksiyonlar ​

Fonksiyonları sahteleme iki farklı kategoriye ayrılabilir: izleme (spying) ve taklit etme (mocking).

Bazen tek ihtiyacınız olan belirli bir fonksiyonun çağrılıp çağrılmadığını (ve muhtemelen hangi argümanların geçirildiğini) doğrulamaktır. Bu durumlarda, doğrudan vi.spyOn() ile kullanabileceğimiz bir gözetleyici yeterli olacaktır (buradan daha fazla bilgi edinin).

Ancak gözetleyiciler yalnızca fonksiyonları izlemenize yardımcı olabilir, bu fonksiyonların uygulamasını değiştiremezler. Bir fonksiyonun sahte (veya taklit edilmiş) bir sürümünü oluşturmamız gerektiği durumlarda, vi.fn() kullanabiliriz (buradan daha fazla bilgi edinin).

Fonksiyonları sahteleme için bir temel olarak Tinyspy kullanıyoruz, ancak onu jest uyumlu hale getirmek için kendi sarmalayıcımız var. Hem vi.fn() hem de vi.spyOn() aynı metotları paylaşır, ancak yalnızca vi.fn()'nin dönüş sonucu çağrılabilir.

Örnek ​

js
import { afterEach, describe, expect, it, vi } from 'vitest';

function getLatest(index = messages.items.length - 1) {
  return messages.items[index];
}

const messages = {
  items: [
    { message: 'Simple test message', from: 'Testman' },
    // ...
  ],
  getLatest, // `getter` veya `setter` özellikleri destekleniyorsa kullanılabilir
};

describe('mesajları okuma', () => {
  afterEach(() => {
    vi.restoreAllMocks();
  });

  it('bir spy ile en son mesajı almalı', () => {
    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('bir mock ile almalı', () => {
    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 ​

  • Jest'in Sahte Fonksiyonları

Global Değişkenler ​

vi.stubGlobal yardımcısını kullanarak jsdom veya node ile mevcut olmayan global değişkenleri sahteleştirebilirsiniz. Global değişkenin değerini bir globalThis nesnesine yerleştirecektir.

ts
import { vi } from 'vitest';

const IntersectionObserverMock = vi.fn(() => ({
  disconnect: vi.fn(),
  observe: vi.fn(),
  takeRecords: vi.fn(),
  unobserve: vi.fn(),
}));

vi.stubGlobal('IntersectionObserver', IntersectionObserverMock);

// artık `IntersectionObserver` veya `window.IntersectionObserver` olarak erişebilirsiniz

Modüller ​

Sahte modüller, bazı diğer kodlarda çağrılan üçüncü parti kütüphaneleri gözlemlemenizi ve argümanları, çıktıyı test etmenize veya 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 Sahteleme Algoritması ​

Kodunuz, bu modül için herhangi bir ilişkili __mocks__ dosyası veya factory olmadan sahte bir modülü içe aktarıyorsa, Vitest modülün kendisini sahteleyecektir. Bu işlem, modülü çağırarak ve her dışa aktarmayı sahteleyerek gerçekleştirilir.

Aşağıdaki prensipler geçerlidir:

  • Tüm diziler boşaltılacaktır
  • Tüm ilkel (primitive) ve koleksiyonlar aynı kalacaktır
  • Tüm nesneler derinlemesine klonlanacaktır
  • Tüm sınıf örnekleri ve prototipleri derinlemesine klonlanacaktır

Örnek ​

js
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { Client } from 'pg';
import { failure, success } from './handlers.js';

// işleyiciler
export function success(data) {}
export function failure(data) {}

// todoları 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('bir todo öğesi listesi alma', () => {
  let client;

  beforeEach(() => {
    client = new Client();
  });

  afterEach(() => {
    vi.clearAllMocks();
  });

  it('öğeleri başarıyla döndürmeli', 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('bir hata fırlatmalı', 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 });
  });
});

İstekler ​

Vitest Node'da çalıştığı için, ağ isteklerini taklit etmek zordur; web API'leri kullanılamaz, bu nedenle ağ davranışını simüle edecek bir mekanizmaya ihtiyacımız var. Bunu başarmak için Mock Service Worker öneriyoruz. Hem REST hem de GraphQL ağ isteklerini sahtelemenize olanak tanır ve çerçeveden bağımsızdır.

Mock Service Worker (MSW), testlerinizin yaptığı istekleri engelleyerek çalışır ve herhangi bir uygulama kodunuzu değiştirmeden kullanmanıza olanak tanır. Tarayıcıda bu, Service Worker API kullanır. Node.js'de ve Vitest için node-request-interceptor kullanır. MSW hakkında daha fazla bilgi edinmek için giriş belgesini okuyun.

Yapılandırma ​

Yapılandırma dosyanızda aşağıdaki gibi kullanabilirsiniz:

js
import { afterAll, afterEach, beforeAll } from 'vitest';
import { setupServer } from 'msw/node';
import { graphql, rest } from 'msw';

const posts = [
  {
    userId: 1,
    id: 1,
    title: 'first post title',
    body: 'first post body',
  },
  // ...
];

export const restHandlers = [
  rest.get('https://rest-endpoint.example/path/to/posts', (req, res, ctx) => {
    return res(ctx.status(200), ctx.json(posts));
  }),
];

const graphqlHandlers = [
  graphql.query(
    'https://graphql-endpoint.example/api/v1/posts',
    (req, res, ctx) => {
      return res(ctx.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 için önemli`)
afterEach(() => server.resetHandlers());

Sunucuyu onUnhandleRequest: 'error' ile yapılandırmak, eşleşen bir istek işleyicisi olmayan bir istek olduğunda bir hata fırlatılmasını sağlar.

Örnek ​

MSW kullanan tam çalışan bir örneğimiz var: MSW ile React Testi.

Daha Fazla ​

MSW'de çok daha fazlası var. Çerezlere ve sorgu parametrelerine erişebilir, sahte 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ını veya aralıkları içeren kodu test ettiğimizde, testlerimizin beklemesini veya zaman aşımına uğramasını sağlamak yerine, setTimeout ve setInterval çağrılarını sahteleyen "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 ​

js
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('gecikmeli yürütme', () => {
  beforeEach(() => {
    vi.useFakeTimers();
  });
  afterEach(() => {
    vi.restoreAllMocks();
  });
  it('fonksiyonu yürütmeli', () => {
    executeAfterTwoHours(mock);
    vi.runAllTimers();
    expect(mock).toHaveBeenCalledTimes(1);
  });
  it('fonksiyonu yürütmemeli', () => {
    executeAfterTwoHours(mock);
    // 2ms ilerletmek işlevi tetiklemeyecektir
    vi.advanceTimersByTime(2);
    expect(mock).not.toHaveBeenCalled();
  });
  it('her dakika yürütmeli', () => {
    executeEveryMinute(mock);
    vi.advanceTimersToNextTimer();
    expect(mock).toHaveBeenCalledTimes(1);
    vi.advanceTimersToNextTimer();
    expect(mock).toHaveBeenCalledTimes(2);
  });
});

Hızlı Başvuru ​

INFO

Aşağıdaki örneklerdeki vi doğrudan vitestten içe aktarılır. Yapılandırmanızda globals'ı true olarak ayarlarsanız, global olarak da kullanabilirsiniz.

Şunları yapmak istiyorum:

  • Bir method üzerinde izleme yapmak
ts
const instance = new SomeClass();
vi.spyOn(instance, 'method');
  • Dışa aktarılmış değişkenleri mocklamak
js
// some-path.js
export const getter = 'variable';
ts
// some-path.test.ts
import * as exports from './some-path.js';

vi.spyOn(exports, 'getter', 'get').mockReturnValue('mocked');
  • Dışa aktarılmış fonksiyonu mocklamak

vi.mock ile örnek:

ts
// ./some-path.js
export function method() {}
ts
import { method } from './some-path.js';

vi.mock('./some-path.js', () => ({
  method: vi.fn(),
}));

WARNING

vi.mock çağrısının dosyanın en üstüne taşındığını unutmayın. vi.mock çağrılarını beforeEach içine yerleştirmeyin, aksi takdirde bunlardan yalnızca biri bir modülü mocklayacaktır.

vi.spyOn ile örnek:

ts
import * as exports from './some-path.js';

vi.spyOn(exports, 'method').mockImplementation(() => {});
  • Dışa aktarılmış sınıf uygulamasını mocklamak

vi.mock ve prototip ile örnek:

ts
// some-path.ts
export class SomeClass {}
ts
import { SomeClass } from './some-path.js';

vi.mock('./some-path.js', () => {
  const SomeClass = vi.fn();
  SomeClass.prototype.someMethod = vi.fn();
  return { SomeClass };
});
// SomeClass.mock.instances SomeClass örneklerini içerecektir

vi.mock ve dönüş değeri ile örnek:

ts
import { SomeClass } from './some-path.js';

vi.mock('./some-path.js', () => {
  const SomeClass = vi.fn(() => ({
    someMethod: vi.fn(),
  }));
  return { SomeClass };
});
// SomeClass.mock.returns döndürülen nesneyi içerecektir

vi.spyOn ile örnek:

ts
import * as exports from './some-path.js';

vi.spyOn(exports, 'SomeClass').mockImplementation(() => {
  // ilk iki örnekteki uygun olan uygulamayı seçebilirsiniz
});
  • Bir fonksiyondan döndürülen bir nesneyi izlemek

Önbellek kullanarak örnek:

ts
// some-path.ts
export function useObject() {
  return { method: () => true };
}
ts
// useObject.js
import { useObject } from './some-path.js';

const obj = useObject();
obj.method();
ts
// useObject.test.js
import { useObject } from './some-path.js';

vi.mock('./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.js içinde çağrıldı
expect(obj.method).toHaveBeenCalled();
  • Bir modülün bir bölümünü mocklamak
ts
import { mocked, original } from './some-path.js';

vi.mock('./some-path.js', async () => {
  const mod = await vi.importActual<typeof import('./some-path.js')>(
    './some-path.js'
  );
  return {
    ...mod,
    mocked: vi.fn(),
  };
});
original(); // orijinal davranışa sahip
mocked(); // bir izleme fonksiyonu
  • Geçerli tarihi mocklamak

Date'in zamanını mocklamak için vi.setSystemTime yardımcı fonksiyonunu kullanabilirsiniz. Bu değer, farklı testler arasında otomatik olarak sıfırlanmayacaktır.

vi.useFakeTimers kullanmanın Date'in zamanını da değiştirdiğine dikkat edin.

ts
const mockDate = new Date(2022, 0, 1);
vi.setSystemTime(mockDate);
const now = new Date();
expect(now.valueOf()).toBe(mockDate.valueOf());
// taklit edilen zamanı sıfırlamak için
vi.useRealTimers();
  • Global değişkeni mocklamak

globalThis'e bir değer atayarak veya vi.stubGlobal yardımcısını kullanarak global değişken ayarlayabilirsiniz. vi.stubGlobal kullanırken, unstubGlobals yapılandırma seçeneğini etkinleştirmediğiniz veya vi.unstubAllGlobals çağırmadığınız sürece, bu değer farklı testler arasında otomatik olarak sıfırlanmayacaktır.

ts
vi.stubGlobal('__VERSION__', '1.0.0');
expect(__VERSION__).toBe('1.0.0');
  • import.meta.env'yi mocklamak

Ortam değişkenini değiştirmek için, ona yeni bir değer atayabilirsiniz. Bu değer, farklı testler arasında otomatik olarak sıfırlanmayacaktır.

ts
import { beforeEach, expect, it } from 'vitest';

// beforeEach kancasında manuel olarak sıfırlayabilirsiniz
const originalViteEnv = import.meta.env.VITE_ENV;

beforeEach(() => {
  import.meta.env.VITE_ENV = originalViteEnv;
});

it('değeri değiştirir', () => {
  import.meta.env.VITE_ENV = 'staging';
  expect(import.meta.env.VITE_ENV).toBe('staging');
});

Değeri otomatik olarak sıfırlamak istiyorsanız, unstubEnvs yapılandırma seçeneği etkinleştirilmişken vi.stubEnv yardımcısını kullanabilirsiniz (veya beforeEach kancasında manuel olarak vi.unstubAllEnvs çağırın):

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

// testlerin çalıştırılmasından önce "VITE_ENV" "test"tir
import.meta.env.VITE_ENV === 'test';

it('değeri değiştirir', () => {
  vi.stubEnv('VITE_ENV', 'staging');
  expect(import.meta.env.VITE_ENV).toBe('staging');
});

it('değer, başka bir test çalıştırılmadan önce eski haline döner', () => {
  expect(import.meta.env.VITE_ENV).toBe('test');
});
ts
// vitest.config.ts
export default {
  test: {
    unstubAllEnvs: true,
  },
};
Pager
Önceki sayfaAnlık Görüntü (Snapshot) Testleri
Sonraki sayfaTür Testleri

MIT Lisansı altında yayınlanmıştır.

Copyright (c) 2024 Mithril Contributors

https://v0.vitest.dev/guide/mocking

MIT Lisansı altında yayınlanmıştır.

Copyright (c) 2024 Mithril Contributors