API Test Süreçlerindeki Zorluklar
Harici HTTP hizmetlerine bağlı kodları test etmek zorlu bir süreçtir. Üç ana seçeneğiniz var:
- Gerçek API’yi her seferinde çağırın. Bu yöntem, yavaş ve hata olasılığı yüksek testler yapmanıza neden olur. CI (Continuous Integration) ortamında çalıştırıldığında, üçüncü partinin üzerinize limit koyma riski ile karşı karşıya kalırsınız.
- Manuel olarak
Http::fake()yazın. Yanıtınızı bir kez yakalarsınız, sabit kodlarsınız ve gerçek verilerle senkronize tutmak sizin sorumluluğunuzda olur. Bu, genellikle unutulur ve API değiştiklerinde testleriniz geçmeye devam eder ancak yanlış sonuçlar verir. - Hiçbir şey yazmayın. O katmanı tamamen atlamak ise ideal değildir.
<p>Http Automock, bu duruma farklı bir yaklaşım getiriyor; ilk çalıştırmada gerçek istek yaparak yanıtı diske kaydediyor, sonrasında ise kaydedilen yanıtlar yeniden oynatılıyor.</p>
<h2>
Nasıl Çalışır?
</h2>
<p>Paketin kurulumunu bir dev bağımlılığı olarak yapıyorsunuz:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight" dir="auto">
<pre>composer require michiruf/laravel-http-automock --dev</pre>
</div>
<p>Ayrıca, testinizin içinde bir satır eklemeniz yeterli:</p>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto js-code-highlight" dir="auto">
<pre><span class="pl-en">it</span>(<span class="pl-s>'<span class="pl-s">API'den sıcak kahve alır</span>'</span>,
<span class="pl-k">function</span> () {
Http::<span class="pl-en">automock</span>();
<span class="pl-s1"><span class="pl-c1">$</span>response</span> = Http::<span class="pl-en">get</span>(<span class="pl-s>'<span class="pl-s">https://api.example.com/coffee/hot</span>'</span>)-><span class="pl-en">json</span>();
<span class="pl-en">expect</span>(<span class="pl-s1"><span class="pl-c1">$</span>response</span>)-><span class="pl-en">toHaveCount</span>(<span class="pl-mi">20</span>);
});</pre>
</div>
<p>Bu test ilk çalıştığında gerçek API'ye erişir ve yanıtı .mock uzantılı bir dosyaya kaydeder. Her koşuldan sonraki çalışmalarda ise bu mock dosyası yeniden oynatılır, böylece ağ bağlantısına ihtiyaç duyulmaz.</p>
<h2>
Manuel Fake'lerden Neden Daha İyi?
</h2>
<p>Önemli avantajlardan biri, <strong>mock dosyalarının deposunda yer almasıdır</strong>. Bu, şu anlama geliyor:</p>
<ul>
<li><strong>Git ile API değişikliklerini takip edebilirsiniz.</strong> Mock'larınızı yenilediğinizde ve yanıt farkı görünüyorsa, buna dikkat etmelisiniz.</li>
<li><strong>Gerçek veri güvenilirliği sağlarsınız.</strong> İlk çalışma, canlı servisle olduğu için yanıt yapısının doğru olmasını garanti eder.</li>
</ul>
<h2>
Önemli Yapılandırma Seçenekleri
</h2>
<p>Http Automock, farklı iş akışlarına uyacak şekilde bir dizi seçenek sunar. Gözde bulduğum birkaç seçenek:</p>
<h3>
Gerçek İstekleri Önleme
</h3>
<p><code>preventUnknownRealRequests()</code> ile henüz bir mock dosyası olmayan herhangi bir istek için bir istisna fırlatabilirsiniz:</p>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto js-code-highlight" dir="auto">
<pre><span class="nc">Http</span>::<span class="nf">automock</span><span class="p">()-><span class="nf">preventUnknownRealRequests</span>();</span></pre>
</div>
<h3>
Yenileme / Eski Mock'ları Temizleme
</h3>
<p>Bir API yanıt formatı değiştiğinde, testlerinizi <code>renew()</code> veya <code>prune()</code> ile çalıştırarak her şeyi yeniden alabilir ve mevcut dosyaları üzerine yazabilirsiniz:</p>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto js-code-highlight" dir="auto">
<pre><span class="nc">Http</span>::<span class="nf">automock</span><span class="p">()-><span class="nf">renew</span>();</span></pre>
</div>
<h3>
Mock'ları Canlı Yanıtlarla Doğrulama
</h3>
<p>Herhangi bir şeyi üzerine yazmadan drift algılamak istiyorsanız, <code>validateMocks()</code> gerçek istek yapar ve bunları kaydedilmiş dosyalarla karşılaştırır:</p>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto js-code-highlight" dir="auto">
<pre><span class="nc">Http</span>::<span class="nf">automock</span><span class="p">()-><span class="nf">validateMocks</span>();</span></pre>
</div>
<h3>
Belirli İstekleri Atlama
</h3>
<p>Her şeyin mocklanması gerekmez. URL deseni, HTTP metodu veya özel bir closure ile istekleri dışlayabilirsiniz:</p>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto js-code-highlight" dir="auto">
<pre><span class="nc">Http</span>::<span class="nf">automock</span><span class="p">()-><span class="nf">skip</span>(<span class="s1>'*oauth.example.com*'</span>, <span class="s1>'auth'</span>);</span>
<span class="nc">Http</span>::<span class="nf">automock</span><span class="p">()-><span class="nf">skipPost</span>(); </span><span class="c1">// POST isteklerini geç</span></pre>
</div>
<h3>
Dosya İsimlerini Özelleştirme
</h3>
<p>Varsayılan dosya adı formatı <code>1_GET_4c147242.mock</code> şeklindedir. İnsan tarafından okunabilir alt dizinler istiyorsanız, <code>url_subdirectory</code> çözücüsüne geçiş yapabilirsiniz:</p>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto js-code-highlight" dir="auto">
<pre><span class="nc">Http</span>::<span class="nf">automock</span><span class="p">()-><span class="nf">resolveFileNameUsing</span>(<span class="s1>'url_subdirectory'</span>);</span></pre>
</div>
<h3>
Yanıt Başlıklarını Koruma
</h3>
<p>Varsayılan olarak yalnızca yanıt gövdesi kaydedilir. Kodunuz başlıklara göre dallanıyorsa, bu başlıkları da dahil etmelisiniz:</p>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto js-code-highlight" dir="auto">
<pre><span class="nc">Http</span>::<span class="nf">automock</span><span class="p">()-><span class="nf">withHeaders</span>(<span class="s1>['Content-Type', 'X-RateLimit-Remaining']</span>);</span></pre>
</div>
<h2>
Uyum Üzerine Not
</h2>
<p>Http Automock, <code>Http::fake()</code> ile tamamen uyumludur. Mevcut testleriniz hem gerçek hem de sahte istekleri karıştırıyorsa, her ikisiyle de uyumlu çalışır. Ayrıca, <code>mockHttpFakes()</code> kullanarak mevcut bir suite'i taşırken inline fake'leri mock dosyalarına da kaydedebilirsiniz.</p>
<p><strong>Gereksinimler:</strong> PHP 8.2+, Laravel 11+, ve <a href="https://pestphp.com/" target="_blank" rel="noopener noreferrer">Pest</a>.</p>
<h2>
Sonuç
</h2>
<p>Temel fikir basittir: Harici API yanıtlarını snapshot testleri ile aynı şekilde ele alın. Bir kez kaydedin, taahhütte bulunun ve yeniden oynatın. Snapshot testlerden farkı ise, çıktı/ beklentileri değil, harici servislerden gelen girdileri kaydetmenizdir.</p>
<p>Laraavel ve Pest ile geliştirme yapıyorsanız ve sahte verilerle uğraşmaktan bıktıysanız, denemelisiniz.</p>
<p>Herhangi bir geri dönüş memnuniyetle karşılanır.</p>
<p><a href="https://github.com/michiruf/laravel-http-automock" class="ltag_cta ltag_cta--branded" role="button" target="_blank" rel="noopener noreferrer">GitHub'daki Repo'ya Göz Atın</a></p>Kaynak: Orijinal Makale


