Skip to content
Vitest 3
Main Navigation Kılavuz & APIYapılandırmaTarayıcı ModuGelişmiş API
3.2.0
2.1.9
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

Giriş

Neden Vitest

Başlarken

Özellikler

Vitest'i Yapılandırma

API

Test API Referansları

Mock Fonksiyonlar

Vi

expect

expectTypeOf

assert

assertType

Kılavuz

Komut Satırı Arayüzü

Test Filtreleme

Test Projeleri

Raporlayıcılar

Kapsam

Anlık Görüntüler

Mocking

Paralellik

Tür Testleri

Vitest UI

Kaynak İçi Test

Test Ortamı

Test Açıklamaları

Test Ortamı

Eşleştiricileri Genişletme

IDE Entegrasyonları

Hata Ayıklama

Sık Karşılaşılan Hatalar

Geçiş Kılavuzu

Vitest 3.0'a Geçiş

Jest'ten Geçiş

Performans

Test Performansını Profillendirme

Performansı İyileştirme

Tarayıcı Modu

Gelişmiş API

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

Bu sayfada

Mocking ​

Test yazarken, dahili veya harici bir servisin "sahte" bir versiyonunu oluşturmanız sadece bir zaman meselesidir. Bu genellikle mocking olarak adlandırılır. Vitest, vi yardımcısı aracılığıyla size yardımcı olacak yardımcı fonksiyonlar sağlar. Bunu vitest'ten içe aktarabilir veya global yapılandırması etkinse global olarak erişebilirsiniz.

WARNING

Test çalıştırmaları arasında mock durum değişikliklerini geri almak için, her test çalıştırmasından önce veya sonra mock'ları temizlemeyi veya geri yüklemeyi mutlaka unutmayın! Daha fazla bilgi için mockReset belgelerine bakın.

vi.fn, vi.mock veya vi.spyOn yöntemlerine aşina değilseniz, önce API bölümüne göz atın.

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 ​

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('purchasing flow', () => {
  beforeEach(() => {
    // vitest'e sahte zaman kullandığımızı bildir
    vi.useFakeTimers();
  });

  afterEach(() => {
    // her test çalıştırmasından sonra tarihi eski haline getir
    vi.useRealTimers();
  });

  it('allows purchases within business hours', () => {
    // mesai 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('disallows purchases outside of business hours', () => {
    // mesai 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ı mock'lamak iki farklı kategoriye ayrılabilir: spying ve mocking.

Bazen tek ihtiyacınız olan belirli bir fonksiyonun çağrılıp çağrılmadığını (ve belki hangi argümanların geçirildiğini) doğrulamaktır. Bu durumlarda doğrudan vi.spyOn() ile kullanabileceğimiz bir spy yeterli olacaktır (daha fazlasını buradan okuyun).

Ancak spy'lar size sadece fonksiyonları izleme konusunda yardımcı olabilir, bu fonksiyonların uygulamasını değiştiremezler. Bir fonksiyonun sahte (veya mock'lanmış) bir versiyonunu oluşturmamız gereken durumlarda vi.fn() kullanabiliriz (daha fazlasını buradan okuyun).

Fonksiyonları mock'lamak için temel olarak Tinyspy kullanıyoruz, ancak jest uyumluluğu sağlamak amacıyla kendi sarmalayıcımızı geliştirdik. Hem vi.fn() hem de vi.spyOn() aynı yöntemleri paylaşır, ancak yalnızca vi.fn()'nin dönüş sonucu çağrılabilir.

Örnek ​

js
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 Fazlası ​

  • Jest'in Mock Fonksiyonları

Globaller ​

jsdom veya node ile bulunmayan global değişkenleri vi.stubGlobal yardımcısını kullanarak mock'layabilirsiniz. Bu, 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);

// ş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üphanelerin davranışını taklit eder, böylece argümanları, çı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ı mock'layarak otomatik olarak bir mock oluşturacaktı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 derinlemesine klonlanacaktır
  • Sınıfların tüm örnekleri ve prototipleri derinlemesine klonlanacaktır

Sanal Modüller ​

Vitest, Vite sanal modüllerini mock'lamayı destekler. Jest'te sanal modüllerin ele alınışından farklı çalışır. vi.mock fonksiyonuna virtual: true 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:

  1. Bir takma ad sağlayın
ts
import { defineConfig } from 'vitest/config';
import { resolve } from 'node:path';
export default defineConfig({
  test: {
    alias: {
      '$app/forms': resolve('./mocks/forms.js'),
    },
  },
});
  1. Sanal bir modülü çözen bir eklenti sağlayın
ts
import { defineConfig } from 'vitest/config';
export default defineConfig({
  plugins: [
    {
      name: 'virtual-modules',
      resolveId(id) {
        if (id === '$app/forms') {
          return 'virtual:$app/forms';
        }
      },
    },
  ],
});

İkinci yaklaşımın faydası, farklı sanal giriş noktalarını dinamik olarak oluşturabilmenizdir. Birden fazla sanal modülü tek bir dosyaya yönlendirirseniz, hepsi vi.mock'tan etkilenecektir, 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ı mock'lamanın mümkün olmadığını unutmayın. Örneğin, bu kodda:

ts
export function foo() {
  return 'foo';
}

export function foobar() {
  return `${foo()}bar`;
}

foo yöntemi doğrudan referans alındığı için dışarıdan mock'lanamaz. Bu nedenle bu kodun foobar içindeki foo çağrısı üzerinde hiçbir etkisi olmayacaktır (ancak diğer modüllerdeki foo çağrısını etkileyecektir):

ts
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 uygulamayı sağlayarak doğrulayabilirsiniz:

ts
import * as mod from './foobar.js';

vi.spyOn(mod, 'foo');

// dışa aktarılan foo mock'lanmış yöntemi referans alır
mod.foobar(mod.foo);
ts
export function foo() {
  return 'foo';
}

export function foobar(injectedFoo) {
  return injectedFoo === foo; // false
}

Bu beklenen bir 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 gibi teknikleri kullanarak uygulama mimarinizi iyileştirmeyi düşünün.

Örnek ​

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

// todo'ları 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 mock'lamak, testlerin gerçek dosya sistemine bağlı olmamasını sağlayarak testleri daha güvenilir ve öngörülebilir hale getirir. Bu izolasyon sayesinde önceki testlerden kaynaklanan yan etkilerden kaçınılması kolaylaşır. İ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, varsayılan olarak herhangi bir dosya sistemi mocking API'si sağlamaz. fs modülünü manuel olarak mock'lamak için vi.mock kullanabilirsiniz, ancak bunu sürdürmek 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 sistemi üzerindeki olası yan etkileri önler.

Örnek ​

Her fs çağrısını memfs'e otomatik olarak yönlendirmek için projenizin kökünde __mocks__/fs.cjs ve __mocks__/fs/promises.cjs dosyalarını oluşturabilirsiniz:

ts
// `import` da kullanabiliriz, ancak o zaman
// her dışa aktarma açıkça tanımlanmalıdır

const { fs } = require('memfs');
module.exports = fs;
ts
// `import` da kullanabiliriz, ancak o zaman
// her dışa aktarma açıkça tanımlanmalıdır

const { fs } = require('memfs');
module.exports = fs.promises;
ts
import { readFileSync } from 'node:fs';

export function readHelloWorld(path) {
  return readFileSync(path, 'utf-8');
}
ts
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 mock'lanacaksa 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', () => {
  // birden fazla 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 mock'lamak 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. http, WebSocket ve GraphQL ağ isteklerini mock'lamanıza olanak tanır ve çerçeve bağımsızdır.

Mock Service Worker (MSW), testlerinizin yaptığı istekleri yakalayarak çalışır ve uygulama kodunuzda herhangi bir değişiklik yapmadan 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:

js
import { afterAll, afterEach, beforeAll } from 'vitest';
import { setupServer } from 'msw/node';
import { 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 server = setupServer(...restHandlers);

// Tüm testlerden önce sunucuyu dinlemeye başla
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));

// Tüm testlerden sonra sunucuyu kapat
afterAll(() => server.close());

// Test izolasyonu için her testten sonra işleyicileri resetle
afterEach(() => server.resetHandlers());
js
import { afterAll, afterEach, beforeAll } from 'vitest';
import { setupServer } from 'msw/node';
import { graphql, HttpResponse } from 'msw';

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

const graphqlHandlers = [
  graphql.query('ListPosts', () => {
    return HttpResponse.json({
      data: { posts },
    });
  }),
];

const server = setupServer(...graphqlHandlers);

// Tüm testlerden önce sunucuyu dinlemeye başla
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));

// Tüm testlerden sonra sunucuyu kapat
afterAll(() => server.close());

// Test izolasyonu için her testten sonra işleyicileri resetle
afterEach(() => server.resetHandlers());
js
import { afterAll, afterEach, beforeAll } from 'vitest';
import { setupServer } from 'msw/node';
import { ws } from 'msw';

const chat = ws.link('wss://chat.example.com');

const wsHandlers = [
  chat.addEventListener('connection', ({ client }) => {
    client.addEventListener('message', event => {
      console.log('Received message from client:', event.data);
      // Alınan mesajı istemciye geri gönder
      client.send(`Server received: ${event.data}`);
    });
  }),
];

const server = setupServer(...wsHandlers);

// Tüm testlerden önce sunucuyu dinlemeye başla
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));

// Tüm testlerden sonra sunucuyu kapat
afterAll(() => server.close());

// Test izolasyonu için her testten sonra işleyicileri resetle
afterEach(() => server.resetHandlers());

Sunucuyu onUnhandledRequest: 'error' ile yapılandırmak, karşılık gelen bir istek işleyicisi olmayan bir istek olduğunda bir hata fırlatılmasını sağlar.

Daha Fazlası ​

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 yapabileceklerinizin tamamını görmek için belgelerini okuyun.

Zamanlayıcılar ​

Zaman aşımları veya aralıkları içeren kodu test ettiğimizde, testlerimizin beklemesi veya zaman aşımına uğraması yerine, setTimeout ve setInterval çağrılarını mock'layan "sahte" zamanlayıcılar kullanarak testlerimizi hızlandırabiliriz.

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('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 çalıştırmaz
    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ı mock'layabilirsiniz - bu doğrudan çalışır. Ş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.

ts
class Dog {
  name: string;

  constructor(name: string) {
    this.name = name;
  }

  static getType(): string {
    return 'animal';
  }

  greet = (): string => {
    return `Hi! My name is ${this.name}!`;
  };

  speak(): string {
    return 'bark!';
  }

  isHungry() {}
  feed() {}
}

Bu sınıfı ES5 fonksiyonlarıyla yeniden oluşturabiliriz:

ts
const Dog = vi.fn(function (name) {
  this.name = name;
  // yapıcıda örnek yöntemleri mock'la, her örnek kendi spy'ına sahip olacaktır
  this.greet = vi.fn(() => `Hi! My name is ${this.name}!`);
});

// statik yöntemlerin doğrudan fonksiyon üzerinde mock'landığına dikkat edin,
// 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 mock'la
// tüm `new Dog()` örnekleri bu spy'ları miras alacak ve paylaşacaktır
Dog.prototype.speak = vi.fn(() => 'loud bark!');
Dog.prototype.feed = vi.fn();

WARNING

Yapıcı fonksiyondan ilkel olmayan bir değer döndürülürse, bu değer yeni ifadenin sonucu olacaktır. Bu durumda [[Prototype]] doğru şekilde bağlanmayabilir:

ts
const CorrectDogClass = vi.fn(function (name) {
  this.name = name;
});

const IncorrectDogClass = vi.fn(name => ({
  name,
}));

const Marti = new CorrectDogClass('Marti');
const Newt = new IncorrectDogClass('Newt');

Marti instanceof CorrectDogClass; // ✅ true
Newt instanceof IncorrectDogClass; // ❌ false!

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 yeniden oluşturursunuz:

ts
import { Dog } from './dog.js';

vi.mock(import('./dog.js'), () => {
  const Dog = vi.fn();
  Dog.prototype.feed = vi.fn();
  // ... diğer mock'lar
  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:

ts
function feed(dog: Dog) {
  // ...
}
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 ve greet ile birlikte) zaten mock'lanmıştır:

ts
const Cooper = new Dog('Cooper');
Cooper.speak(); // loud bark!
Cooper.greet(); // Hi! My name is Cooper!

// çağrının geçerliliğini kontrol etmek için yerleşik assertion'ları kullanabilirsiniz
expect(Cooper.speak).toHaveBeenCalled();
expect(Cooper.greet).toHaveBeenCalled();

const Max = new Dog('Max');

// prototipe atanan yöntemler örnekler arasında paylaşılır
expect(Max.speak).toHaveBeenCalled();
expect(Max.greet).not.toHaveBeenCalled();

Belirli bir örnek için dönüş değerini yeniden atayabiliriz:

ts
const dog = new Dog('Cooper');

// "vi.mocked" bir tür yardımcısıdır, çünkü
// TypeScript, Dog'un mock'lanmış bir sınıf olduğunu bilmediği için,
// fonksiyonun 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 mock'lamak için vi.spyOn(dog, 'name', 'get') yöntemini kullanabiliriz. Bu, mock'lanmış özellik üzerinde spy assertion'ları kullanmayı mümkün kılar:

ts
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 spy'layabilirsiniz.

Hızlı Başvuru ​

INFO

Aşağıdaki örneklerde vi doğrudan vitest'ten içe aktarılmıştır. Yapılandırmanızda globals'ı true olarak ayarlarsanız global olarak da kullanabilirsiniz.

İstiyorum ki…

Dışa aktarılan değişkenleri mock'la ​

js
export const getter = 'variable';
ts
import * as exports from './example.js';

vi.spyOn(exports, 'getter', 'get').mockReturnValue('mocked');

Dışa aktarılan bir fonksiyonu mock'la ​

  1. vi.mock ile örnek:

WARNING

vi.mock çağrısının dosyanın en üstüne taşındığını unutmayın. Her zaman tüm içe aktarmalardan önce yürütülecektir.

ts
export function method() {}
ts
import { method } from './example.js';

vi.mock('./example.js', () => ({
  method: vi.fn(),
}));
  1. vi.spyOn ile örnek:
ts
import * as exports from './example.js';

vi.spyOn(exports, 'method').mockImplementation(() => {});

Dışa aktarılan bir sınıf uygulamasını mock'la ​

  1. vi.mock ve .prototype ile örnek:
ts
export class SomeClass {}
ts
import { SomeClass } from './example.js';

vi.mock(import('./example.js'), () => {
  const SomeClass = vi.fn();
  SomeClass.prototype.someMethod = vi.fn();
  return { SomeClass };
});
// SomeClass.mock.instances, SomeClass'a sahip olacak.
  1. vi.spyOn ile örnek:
ts
import * as mod from './example.js';

const SomeClass = vi.fn();
SomeClass.prototype.someMethod = vi.fn();

vi.spyOn(mod, 'SomeClass').mockImplementation(SomeClass);

Bir fonksiyondan dönen bir nesne üzerinde spy kullan ​

  1. Önbellek kullanarak örnek:
ts
export function useObject() {
  return { method: () => true };
}
ts
import { useObject } from './example.js';

const obj = useObject();
obj.method();
ts
import { useObject } from './example.js';

vi.mock(import('./example.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çerisinde çağrıldı
expect(obj.method).toHaveBeenCalled();

Bir modülün bir kısmını mock'la ​

ts
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ışa sahip
mocked(); // bir spy fonksiyonudur

WARNING

Bunun yalnızca harici erişimi mock'ladığını unutmayın. Bu örnekte, original dahili olarak mocked'ı çağırırsa, her zaman modülde tanımlanan fonksiyonu çağıracaktır, mock fabrikası içindeki fonksiyonu değil.

Geçerli tarihi mock'la ​

Date'in zamanını mock'lamak 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ğini unutmayın.

ts
const mockDate = new Date(2022, 0, 1);
vi.setSystemTime(mockDate);
const now = new Date();
expect(now.valueOf()).toBe(mockDate.valueOf());
// mock'lanmış zamanı sıfırla
vi.useRealTimers();

Global bir değişkeni mock'la ​

Global değişkeni globalThis'e bir değer atayarak veya vi.stubGlobal yardımcısını kullanarak 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ırlanmayacaktır.

ts
vi.stubGlobal('__VERSION__', '1.0.0');
expect(__VERSION__).toBe('1.0.0');

import.meta.env'i mock'la ​

  1. 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 resetlenmeyecektir.

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

// testleri çalıştırmadan önce "VITE_ENV" 'test' değerindedir
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');
});
  1. Değeri/değerleri otomatik olarak resetlemek isterseniz, unstubEnvs yapılandırma seçeneği etkinleştirilmiş olarak (veya beforeEach kancasında vi.unstubAllEnvs manuel olarak çağırarak) vi.stubEnv yardımcısını kullanabilirsiniz:
ts
import { expect, it, vi } from 'vitest';

// testleri çalıştırmadan önce "VITE_ENV" 'test' değerindedir
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');
});
ts
export default defineConfig({
  test: {
    unstubEnvs: true,
  },
});
Pager
Önceki sayfaAnlık Görüntüler
Sonraki sayfaParalellik

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

Copyright (c) 2021-Present Vitest Team

https://vitest.dev/guide/mocking

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

Copyright (c) 2021-Present Vitest Team