ViraStack
  • Akademi
  • Hakkında
  • Destek
Genel BakışKaynaklarKatkı
ViraStack

Frontend geliştiricileri için DX odaklı araç seti: starter’lar, ajan kuralları, form hook’ları ve rehber.

Ürünler

  • ViraStack Start
  • ViraStack AI
  • ViraStack Mask
  • ViraStack Password
  • ViraStack Guide

Keşfet

  • Akademi
  • Hakkında
  • Marka
  • Destek

© 2026 ViraStack.

Açık kaynak · MIT

Vitest

07 / 12

Asenkron Testler

findBy, waitFor ve fake timers.

Asenkron arayüz nedir?

Bazı değişiklikler hemen olmaz. Örnekler:

  • API yanıtı gelince ürün listesi görünür.

  • Ürün sepete eklenince bildirim çıkar ve 3 saniye sonra kapanır.

Testiniz bu değişikliği beklemelidir. Beklemezseniz test, arayüz güncellenmeden kontrol yapar ve başarısız olur.1

Hangi aracı kullanmalıyım?

DurumAraç
Eleman sonradan görünecekawait screen.findBy...1
Eleman sonradan kaybolacakawait waitFor(() => expect(queryBy...).not.toBeInTheDocument())1
Kod gerçek süre bekliyor (setTimeout) ve beklemek istemiyorsunuzFake timers2

findBy: sonradan görünecek eleman

findBy* elemanı bulana kadar bekler. Süre dolarsa hata fırlatır. Varsayılan süre 1000 ms.3

test("yüklenirken bilgi mesajı, sonra ürünleri gösterir", async () => {
  render(
    <ProductList
      loadProducts={() => Promise.resolve(products)}
      onAddToCart={vi.fn()}
    />,
  );

  expect(screen.getByText("Ürünler yükleniyor...")).toBeInTheDocument();
  expect(await screen.findAllByRole("article")).toHaveLength(3);
});

İlk satırda getBy* kullanıldı. Yükleme mesajı ilk render'da zaten ekrandadır. Bekleme gerekmez.3

waitFor: koşulun doğru olmasını bekleme

waitFor, verdiğiniz fonksiyon hata fırlatmayı bırakana kadar onu tekrar tekrar çalıştırır. Varsayılan süre 1000 ms.1

Bir elemanın kaybolmasını beklerken queryBy* kullanın:3

await waitFor(() =>
  expect(screen.queryByText("Ürünler yükleniyor...")).not.toBeInTheDocument(),
);

Yap

  • waitFor içine yalnızca expect kontrolleri koyun.4

  • Görünmesini beklediğiniz eleman için waitFor yerine findBy kullanın.4

Yapma

  • waitFor içinde user.click gibi işlemler yapmayın. Fonksiyon tekrar çalışınca işlem de tekrar eder.4

  • waitFor içinde findBy kullanmayın. findBy zaten waitFor kullanır.1

Hata

findBy bir Promise döndürür. expect(screen.findByText(...)).not.toBeInTheDocument() yazarsanız expect'e eleman yerine Promise vermiş olursunuz ve jest-dom bunu HTMLElement olmadığı için hata ile reddeder.5 Bir elemanın olmadığını doğrulamak için queryBy kullanın.3

  • waitForElementToBeRemoved(() => screen.queryByText("...")) bir elemanın kaybolmasını bekler. Eleman başta DOM'da olmalıdır. Eleman zaten yoksa fonksiyon hata fırlatır.1

  • Emin değilseniz waitFor ve queryBy kombinasyonunu kullanın. Bu yöntem eleman çok hızlı kaybolsa bile çalışır.1

Fake timers: zamanı kontrol etme

Ürün sepete eklenince bir bildirim görünür. Bildirim 3 saniye sonra kapanır. 3 saniye bekleyen bir test yavaştır. Zamanı kendiniz ilerletin.2

import { useEffect, useState } from "react";

export function AddedToast({ productName }: { productName: string }) {
  const [visible, setVisible] = useState(true);

  useEffect(() => {
    const id = setTimeout(() => setVisible(false), 3000);

    return () => clearTimeout(id);
  }, []);

  return visible ? <div role="status">{productName} sepete eklendi.</div> : null;
}
import { act, render, screen } from "@testing-library/react";
import { AddedToast } from "./AddedToast";

beforeEach(() => {
  vi.useFakeTimers({ shouldAdvanceTime: true });
});

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

test("3 saniye sonra bildirim kaybolur", async () => {
  render(<AddedToast productName="Kablosuz Kulaklık" />);

  expect(await screen.findByRole("status")).toHaveTextContent(
    "Kablosuz Kulaklık sepete eklendi.",
  );

  act(() => {
    vi.advanceTimersByTime(3000);
  });

  expect(screen.queryByRole("status")).not.toBeInTheDocument();
});

Üç kurala dikkat edin:

  • vi.useFakeTimers çağrısını render öncesinde yapın. Component'in setTimeout çağrısı fake olmalıdır.6

  • vi.advanceTimersByTime çağrısını act içine alın. Zamanlayıcı bir React state'ini günceller.7

  • vi.useRealTimers çağrısını afterEach içinde yapın.8 Test hata verse bile afterEach çalışır.

Hata

vi.useFakeTimers() çağrısı findBy ve userEvent çağrılarını bekletir, test timeout hatasıyla biter.9, 8 Çözüm: vi.useFakeTimers({ shouldAdvanceTime: true }).10 userEvent kullanıyorsanız ayrıca userEvent.setup({ advanceTimers: vi.advanceTimersByTime }) yazın.11

  • vi.advanceTimersByTime(ms): zamanı ms kadar ilerletir. vi.advanceTimersByTimeAsync(ms): aynısını yapar, asenkron kurulan zamanlayıcıları da çalıştırır.6

  • vi.runOnlyPendingTimers(): bekleyen zamanlayıcıları hemen çalıştırır. vi.setSystemTime(date): Date.now() ve new Date() değerini ayarlar.6

  • Bekleme süresi kısaysa (300 ms gibi) fake timers kullanmayın. findBy ile bekleyin.

Kendin dene

API çağrısı başarısız olunca ne görünür? Bunu test edin:

  • loadProducts fonksiyonu Promise.reject(new Error("ağ hatası")) döndürür.

  • findByRole("alert") ile Ürünler yüklenemedi. mesajını bulun.

  • queryBy* ile Ürünler yükleniyor... mesajının kaybolduğunu doğrulayın.

Kaynaklar

  • 1DokümanTesting Library: Async Methods

    `findBy`, `waitFor` ve `waitForElementToBeRemoved`.

  • 2DokümanVitest: Timers

    Fake timers rehberi.

  • 3DokümanTesting Library: About Queries

    `getBy`, `queryBy` ve `findBy` farkı.

  • 4MakaleKent C. Dodds: Common mistakes with React Testing Library

    `waitFor` içinde yan etki ve `find*` yerine `waitFor` hataları.

  • 5Repojest-dom: toBeInTheDocument kaynak kodu

    Verilen değerin HTMLElement olup olmadığı kontrol edilir.

  • 6DokümanVitest: vi API

    Fake timers komutları.

  • 7DokümanReact: act

    Güncellemeleri assertion'dan önce uygulama.

  • 8DokümanTesting Library: Using Fake Timers

    Fake timers kurulumu ve temizliği.

  • 9Repodom-testing-library #1218: useFakeTimers ve findBy

    Vitest'te `findBy` timeout'a düşer.

  • 10DokümanVitest: fakeTimers yapılandırması

    `shouldAdvanceTime` seçeneği.

  • 11Dokümanuser-event: Options

    `advanceTimers` seçeneği.

Bu sayfayı düzenle

Son güncelleme tarihi: 14 Ekim 2026

Önceki adım06. Kullanıcı EtkileşimiSonraki adım08. Ürün ListesiProje