DEV Community

Cover image for Test Amaçlı API Mocklama: Uygulamalı Rehber
Tobias Hoffmann
Tobias Hoffmann

Posted on • Originally published at apidog.com

Test Amaçlı API Mocklama: Uygulamalı Rehber

Canlı bir API'ye bağlı testler, kodunuz doğru olsa bile yanlış nedenlerle başarısız olabilir: hazırlık sunucusu çöker, üçüncü taraf hız limiti devreye girer veya bir ekip arkadaşı test verisini değiştirir. API taklidi, gerçek uç noktayı kontrollü bir yedekle değiştirerek testlerinize deterministik yanıtlar verir.

Apidog'u bugün deneyin

Bu rehberde bir API'yi test için nasıl taklit edeceğinizi adım adım uygulayacağız: şema tanımlama, taklit yanıt üretme, taklit sunucu çalıştırma, testleri bu sunucuya yönlendirme ve hata yollarını doğrulama. Örnek olarak küçük bir sipariş yönetimi API'sindeki GET /orders/{id} uç noktasını kullanacağız; aynı yaklaşım REST ve GraphQL servisleri için de geçerlidir.

API'yi ne zaman taklit etmelisiniz?

Ağ katmanını değil, kendi kodunuzu test etmek istiyorsanız API'yi taklit edin. Bu özellikle birim testleri ve çoğu entegrasyon testi için uygundur.

Örneğin istemcinizin şunları doğru yaptığını doğrulamak için gerçek sunucuya ihtiyacınız yoktur:

  • 200 yanıtını ayrıştırmak
  • 404 için anlamlı hata göstermek
  • 429 veya 503 durumlarında yeniden denemek
  • Bozuk JSON geldiğinde çökmemek
  • Yavaş yanıt geldiğinde zaman aşımına düşmek

Gerçek API'yi tamamen bırakmayın. Canlı servise karşı küçük bir sözleşme testi ve uçtan uca test katmanı tutun. Amaç, taklitlerin hâlâ gerçek API sözleşmesiyle uyumlu olduğunu doğrulamaktır.

Kısaca:

  • Hız ve izolasyon için taklit kullanın.
  • Sözleşmeyi doğrulamak için gerçek API kullanın.

Daha fazla bağlam için API taklidinin işe yaradığı senaryolara ve taklit sunucu ile gerçek sunucu arasındaki farka bakabilirsiniz.

Beş adımlı iş akışı

Bir API'yi test için taklit ederken süreç genellikle aynıdır:

  1. Gerçek yanıt şeklini yansıtmak için şemayı tanımlayın.
  2. Bu şemadan statik veya dinamik taklit yanıtlar oluşturun.
  3. Yanıtları bir URL üzerinden sunan taklit sunucuyu çalıştırın.
  4. Test kodunuzdaki temel URL'yi değiştirerek testleri taklit sunucuya yönlendirin.
  5. Gerçek sunucunun isteğe bağlı üretmeyeceği hata yollarını test edin.

Aşağıdaki örneklerde GET /orders/{id} uç noktasını kullanacağız.

Adım 1: Şemayı tanımlayın

Taklit yanıt, gerçek API yanıtıyla aynı yapıda değilse testiniz yanıltıcı olur. Bu yüzden önce şema tanımlayın.

API'nizin zaten bir OpenAPI belgesi varsa onu kullanın. Yoksa en azından test ettiğiniz uç nokta için küçük bir şema yazın.

Örnek GET /orders/{id} tanımı:

paths:
  /orders/{id}:
    get:
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Order found
          content:
            application/json:
              schema:
                type: object
                required:
                  - id
                  - status
                  - total
                  - items
                properties:
                  id:
                    type: string
                  status:
                    type: string
                    enum:
                      - pending
                      - shipped
                      - delivered
                  total:
                    type: number
                  items:
                    type: array
                    items:
                      type: object
        '404':
          description: Order not found
Enter fullscreen mode Exit fullscreen mode

Bu şema iki şey sağlar:

  • Taklit sunucunun hangi alanları döndüreceğini belirler.
  • API sözleşmesi için tek doğruluk kaynağı oluşturur.

Arka uç sözleşmeyi değiştirdiğinde şemayı güncellersiniz. Şemadan türetilen taklitler de bu değişikliği takip eder. Bu yaklaşım, API sözleşme testini güvenilir tutar.

Adım 2: Taklit yanıtları oluşturun

Taklit yanıt üretmek için iki ana yöntem vardır.

Statik yanıt

Statik yanıt, değişmeyen sabit JSON'dur. Özellikle deterministik birim testleri için uygundur.

Örnek:

{
  "id": "order_8842",
  "status": "shipped",
  "total": 149.99,
  "items": [
    {
      "sku": "sku_123",
      "quantity": 1
    },
    {
      "sku": "sku_456",
      "quantity": 2
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Bunu şu durumlarda kullanın:

  • Beklenen yanıtı birebir doğrulamak istiyorsanız
  • Snapshot benzeri testler yazıyorsanız
  • Testin her çalıştırmada aynı veriyle koşmasını istiyorsanız

Dinamik yanıt

Dinamik yanıt, her istek için gerçekçi değerlerle oluşturulur. Örneğin:

  • id için UUID
  • status için enum içinden geçerli bir değer
  • total için makul bir para değeri
  • items için farklı uzunlukta diziler

Dinamik veri, tek bir sabit yükün kaçırabileceği hataları yakalamanıza yardım eder. Örneğin istemciniz boş dizi, uzun metin veya beklenmeyen ama geçerli enum değeriyle bozuluyorsa bunu daha erken görürsünüz.

Çoğu ekip iki yaklaşımı birlikte kullanır:

  • Kritik doğrulamalar için statik yanıt
  • Daha geniş kapsama için dinamik yanıt

Apidog, şemayı okuyarak taklit uç noktası oluşturabilir. email, phone veya avatar gibi alan adlarını uygun veri türleriyle eşleştirip geçerli yanıtlar döndürebilir. Böylece tarayıcıdan veya test kodundan taklit URL'sini çağırarak hızlıca yanıt alabilirsiniz.

Elle yük yazıyorsanız gerçekçi veri kullanın. Aşağıdaki gibi aşırı basit yükler hataları gizleyebilir:

{
  "id": "1",
  "status": "pending",
  "total": 0,
  "items": []
}
Enter fullscreen mode Exit fullscreen mode

Bunun yerine üretime daha yakın veri kullanın:

{
  "id": "order_8842",
  "status": "shipped",
  "total": 149.99,
  "items": [
    {
      "sku": "keyboard-pro",
      "quantity": 1,
      "price": 89.99
    },
    {
      "sku": "mouse-wireless",
      "quantity": 1,
      "price": 60
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Adım 3: Taklit sunucuyu çalıştırın

Taklit yanıt ancak bir sunucu üzerinden sunulduğunda testler tarafından kullanılabilir. İki seçeneğiniz vardır.

Yerel taklit sunucu

Yerel taklit sunucu makinenizde çalışır. Genellikle localhost veya 127.0.0.1 üzerinde bir port dinler.

Örneğin Prism ile OpenAPI dosyasından taklit sunucu başlatabilirsiniz:

prism mock openapi.yaml
# Mock server listening on http://127.0.0.1:4010
Enter fullscreen mode Exit fullscreen mode

Yerel taklit sunucu şunlar için uygundur:

  • Birim testleri
  • Entegrasyon testleri
  • CI içinde izole test çalıştırmaları
  • Çevrimdışı geliştirme

Avantajları:

  • Hızlıdır.
  • Ağ gecikmesi minimumdur.
  • Paylaşılan durum olmadığı için testler birbirini etkilemez.

Bulut taklit sunucu

Bulut taklit sunucunun genel bir URL'si vardır. Şu durumlarda kullanışlıdır:

  • Mobil uygulama fiziksel cihazdan test ediliyorsa
  • CI çalıştırıcısının yerel makinenize erişimi yoksa
  • Harici bir ekip arkadaşı aynı taklite erişmek istiyorsa
  • Demo veya ürün incelemesi yapılıyorsa

Apidog, projeler için barındırılan Bulut Taklit URL'si sağlayabilir. Böylece farklı ağlardaki ekip üyeleri aynı taklit uç noktaya erişebilir.

Genel kural:

  • Otomatik testlerde yerel taklit kullanın.
  • Demo, cihaz testi ve ekip paylaşımı için bulut taklit kullanın.

Adım 4: Testlerinizi taklit sunucuya yönlendirin

Test kodunuz üretim URL'sine sabitlenmiş olmamalıdır. Temel URL'yi yapılandırılabilir yapın.

Örnek istemci:

// orderClient.js
export async function getOrder(id, baseUrl) {
  const response = await fetch(`${baseUrl}/orders/${id}`);

  if (response.status === 404) {
    throw new Error('Order not found');
  }

  if (!response.ok) {
    throw new Error(`Request failed with status ${response.status}`);
  }

  return response.json();
}
Enter fullscreen mode Exit fullscreen mode

Testte temel URL'yi ortam değişkeninden okuyun:

// orderClient.test.js
import { getOrder } from './orderClient.js';

const BASE_URL = process.env.API_BASE_URL || 'http://127.0.0.1:4010';

test('shipped durumundaki siparişi ayrıştırır', async () => {
  const order = await getOrder('order_8842', BASE_URL);

  expect(order.status).toBe('shipped');
  expect(typeof order.total).toBe('number');
  expect(Array.isArray(order.items)).toBe(true);
});
Enter fullscreen mode Exit fullscreen mode

CI içinde testleri taklit sunucuya yönlendirmek için:

API_BASE_URL=http://127.0.0.1:4010 npm test
Enter fullscreen mode Exit fullscreen mode

Bu desenin avantajı şudur: uygulama kodu taklit sunucudan haberdar olmaz. Sadece farklı bir temel URL alır.

Aynı yaklaşım, CI/CD içinde API testlerini otomatikleştirirken de geçerlidir.

Adım 5: Hata yollarını test edin

Gerçek sunucu istediğiniz anda 500, 429 veya yavaş yanıt üretmez. Taklit sunucu ise bunu kontrollü şekilde yapabilir.

Aşağıdaki senaryoları özellikle test edin:

Senaryo Taklit ne döndürür? Ne doğrulanır?
Kayıp kayıt 404 İstemci açık bir "bulunamadı" hatası üretir
Sunucu hatası 500 İstemci yeniden dener veya geri dönüş davranışı uygular
Hız limiti 429 ve Retry-After İstemci doğru süre bekler
Yavaş yanıt 5 sn gecikmeden sonra 200 İstemci zaman aşımını doğru yönetir
Bozuk gövde Bozuk JSON ile 200 İstemci çökmek yerine kontrollü hata üretir

Örnek Jest testi:

test('404 geldiğinde anlamlı hata fırlatır', async () => {
  await expect(getOrder('order_404', BASE_URL)).rejects.toThrow('Order not found');
});
Enter fullscreen mode Exit fullscreen mode

Yeniden deneme davranışı test ediyorsanız istemcinizde retry mantığını izole edin:

export async function getOrderWithRetry(id, baseUrl, retries = 2) {
  let lastError;

  for (let attempt = 0; attempt <= retries; attempt++) {
    try {
      return await getOrder(id, baseUrl);
    } catch (error) {
      lastError = error;
    }
  }

  throw lastError;
}
Enter fullscreen mode Exit fullscreen mode

Test:

test('geçici hata durumunda yeniden dener', async () => {
  const order = await getOrderWithRetry('order_retry', BASE_URL, 2);

  expect(order.id).toBe('order_retry');
});
Enter fullscreen mode Exit fullscreen mode

Apidog'un gelişmiş taklit kuralları, isteğe göre farklı yanıtlar döndürmenizi sağlar. Örneğin order_404 için yapılan istek 404 dönerken diğer kimlikler normal 200 yanıtı alabilir. Bunu API doğrulama ile birleştirerek yalnızca durum kodlarını değil, davranışı da doğrulayabilirsiniz.

Büyüyen test paketinde taklitleri düzenleme

Tek bir taklit uç nokta kolay yönetilir. Ancak test paketi büyüdükçe taklitler hızla dağılabilir. Bunu önlemek için birkaç kural uygulayın.

Taklitleri teste göre değil, servise göre gruplayın

Kötü yapı:

tests/
  checkout/
    mock-order.json
  profile/
    mock-order.json
  admin/
    mock-order.json
Enter fullscreen mode Exit fullscreen mode

Daha sürdürülebilir yapı:

mocks/
  orders/
    order-shipped.json
    order-not-found.json
    order-rate-limited.json
  payments/
    payment-success.json
    payment-declined.json
Enter fullscreen mode Exit fullscreen mode

Ödeme API'si değiştiğinde yirmi test dosyası yerine tek bir servis klasörünü güncellersiniz.

Senaryoya göre adlandırın

Dosya veya fixture adları niyeti açık göstermelidir:

order-shipped.json
order-pending.json
order-not-found.json
order-rate-limited.json
order-malformed-response.json
Enter fullscreen mode Exit fullscreen mode

Böylece başarısız test çıktısı daha okunabilir olur.

Ortak temel yanıt kullanın

Her test için tamamen ayrı JSON yazmayın. Temel bir sipariş tanımlayıp yalnızca gerekli alanı değiştirin.

Örnek:

const baseOrder = {
  id: 'order_8842',
  status: 'shipped',
  total: 149.99,
  items: [
    {
      sku: 'keyboard-pro',
      quantity: 1,
      price: 89.99
    }
  ]
};

const pendingOrder = {
  ...baseOrder,
  status: 'pending'
};

const expensiveOrder = {
  ...baseOrder,
  total: 999.99
};
Enter fullscreen mode Exit fullscreen mode

Bu yaklaşım, sözleşme değişikliğinde tek bir temel yapıyı güncellemenizi sağlar.

API otomasyonu için test paketi tasarlarken uyguladığınız disiplin, taklit veriler için de geçerlidir.

Taklitleri gerçek sözleşmeyle senkron tutma

Taklitlerin en büyük riski sözleşmeden sapmasıdır. Arka uç total alanını amount olarak değiştirir, enum'a yeni değer ekler veya zorunlu alan çıkarır; taklit eski yanıtı döndürmeye devam eder. Testler geçer, üretim bozulur.

Bunu önlemek için iki pratik alışkanlık edinin.

1. Taklitleri aynı şemadan üretin

Taklitleri arka ucun kullandığı OpenAPI belgesinden üretin. Şema değiştiğinde taklit de güncellenir.

Elle yazılmış taklitlerde bu bağlantı yoktur. Bu yüzden manuel fixture kullanıyorsanız bile şemaya karşı doğrulama çalıştırın.

2. Gerçek API'ye karşı küçük sözleşme testleri çalıştırın

Taklit testleri hızlı ve izole olmalıdır. Ancak düzenli olarak gerçek API'ye karşı küçük bir sözleşme testi seti çalıştırın.

Amaç şu soruyu yanıtlamaktır:

Canlı API yanıtı hâlâ şemayla uyumlu mu?

Bu testler başarısız olursa taklitlerinizin de güncellenmesi gerekir.

Örnek ayrım:

npm run test:mock       # Her commit'te hızlı taklit testleri
npm run test:contract   # Belirli aralıklarla veya deploy öncesi gerçek API sözleşme testleri
Enter fullscreen mode Exit fullscreen mode

3. Kod incelemede taklitleri de kontrol edin

Bir pull request API yanıtını değiştiriyorsa, ilgili taklitlerin de güncellenip güncellenmediği kontrol edilmelidir. Taklitleri geçici test yardımcısı değil, sözleşmenin parçası olarak değerlendirin.

Şema, taklit sunucu ve test paketini aynı akışta tutmak istiyorsanız Apidog'u İndirin. Daha geniş araç karşılaştırması için REST API taklit araçları listesini inceleyebilirsiniz.

Sıkça sorulan sorular

Her test için API'yi taklit etmeli miyim?

Hayır. Birim ve entegrasyon testlerinde taklit kullanın. Bunun yanında gerçek API'ye giden küçük bir sözleşme ve uçtan uca test grubu bulundurun. Her şeyi taklit etmek sözleşme sapmasını gizleyebilir.

Statik ve dinamik taklit yanıt arasındaki fark nedir?

Statik yanıt, değişmeyen sabit JSON yüküdür. Tahmin edilebilir doğrulamalar için uygundur.

Dinamik yanıt, her istek için gerçekçi değerlerle üretilir. Tek bir sabit yükün yakalayamayacağı ayrıştırma ve sınır durum hatalarını bulmaya yardımcı olur.

Taklitimin doğru kaldığından nasıl emin olurum?

Takliti arka ucun kullandığı aynı şemadan, ideal olarak OpenAPI belgesinden üretin. Ardından gerçek API'ye karşı düzenli sözleşme testleri çalıştırarak canlı yanıtların hâlâ bu şemayla eşleştiğini doğrulayın.

Taklit sunucu yavaş veya başarısız yanıtları simüle edebilir mi?

Evet. Taklit sunucuyu 500, 429 ve Retry-After başlığı veya gecikmeli 200 döndürecek şekilde yapılandırabilirsiniz. Bu, yeniden deneme, geri çekilme ve zaman aşımı mantığını güvenli şekilde test etmenizi sağlar.

Test için yerel taklit sunucu mu, bulut taklit sunucu mu?

Otomatik test çalıştırmaları için yerel taklit sunucu kullanın. Daha hızlıdır ve paylaşılan durum riskini azaltır.

Mobil cihaz, CI ortamı veya harici ekip üyesi yerel makinenize erişemiyorsa bulut taklit sunucu kullanın.

Top comments (0)