Test doubles (mock, stub)
Bağımlılıkları izole etmek için mock ve stub kullanmayı öğrenirsin.
Test double nedir?
Bazı sınıflar dış servislere bağımlıdır: veritabanı, e-posta, ödeme. Bunları her testte çağırmak yavaş ve kırılgandır. Test double, bu bağımlığın sahte bir sürümüdür; gerçek yan etkiler olmadan testin hızlı ve öngörülebilir olmasını sağlar. PHPUnit'de getMockBuilder ile oluşturulur: $this->getMockBuilder(PaymentGateway::class)->getMock(). Stub yalnızca sabit yanıt döner; Mock çağrıların yapılıp yapılmadığını da denetler.
Stub ve mock farkı
Stub, çağrılana önceden belirlenmiş yanıt döner: $stub->method('charge')->willReturn(true). İçten çok, çağrıldığını umursamaz. Mock ise çağrıların yapılıp yapılmayacağını da bekler: $mock->expects($this->once())->method('charge')->with(99.0). Çağrılmazsa test başarısız olur. Kolay anımsa: stub konuşur, mock dinler. Çoğu durumda stub yeter; yalnızca etkileşimi denetlemek gerektiğinde mock kullan.
Uygulama Stub ile bağımlığı izole et
OrderProcessor, PaymentGateway bağımlığıyla çalışır. StubPaymentGateway adında bir stub yaz (her zaman true döner). OrderProcessorTest sınıfını TestCase'ten türet. testCheckoutCallsGateway metodunda stub ile OrderProcessor oluştur, checkout(99.0) çağır, assertTrue ile true döndüğünü denetle.
Örnek çözümü göster
bool { return true; } } yaz. class OrderProcessorTest extends TestCase içinde testCheckoutCallsGateway: $stub = new StubPaymentGateway(); $processor = new OrderProcessor($stub); $this->assertTrue($processor->checkout(99.0)); ekle.
Örnek çözüm:
<?php
// Bu derste TestCase'i basitçe tanımlıyoruz
class TestCase {
protected function assertTrue($condition): void {
if ($condition !== true) { throw new Exception("Koşul true değil"); }
}
}
interface PaymentGateway {
public function charge(float $amount): bool;
}
class OrderProcessor {
private PaymentGateway $gateway;
public function __construct(PaymentGateway $gateway) { $this->gateway = $gateway; }
public function checkout(float $amount): bool {
return $this->gateway->charge($amount);
}
}
class StubPaymentGateway implements PaymentGateway {
public function charge(float $amount): bool { return true; }
}
class OrderProcessorTest extends TestCase {
public function testCheckoutCallsGateway(): void {
$stub = new StubPaymentGateway();
$processor = new OrderProcessor($stub);
$this->assertTrue($processor->checkout(99.0));
}
}
// Testi çalıştır
$test = new OrderProcessorTest();
$test->testCheckoutCallsGateway();
echo "testCheckoutCallsGateway: BAŞARILI\n";
Kendini test et
-
getMockBuilder çağrısını tamamla
<?php $gateway = $this->____(PaymentGateway::class) ->disableOriginalConstructor() ->getMock();Cevabı göster
<?php $gateway = $this->getMockBuilder(PaymentGateway::class) ->disableOriginalConstructor() ->getMock(); -
getMockBuilder ne döner?
- Doğrudan bir mock nesnesi
- Bir MockBuilder örneği
- Sınanacak sınıfın kendisi
- Bir Exception
Cevabı göster
Bir MockBuilder örneği — Doğru. getMockBuilder bir MockBuilder döner; getMock() ile mock nesnesi alınır.
-
Test double türlerini eşleştir
- Stub
- Sabit yanıt döner
- Mock
- Çağrıyı denetler
- Real
- Gerçek servis
- getMock
- Mock üretir