Laravel Testing 2026: Pest, Mocking ve Teknik Mülakat Soruları
Laravel uygulamalarında Pest ile test yazma, facade mocking, mimari testler ve mutation testing konularını kapsamlı bir şekilde inceleyen rehber. Teknik mülakatlara hazırlık için pratik kod örnekleri ve sık sorulan sorular.

Laravel ekosisteminde test yazmak, modern PHP geliştirme süreçlerinin vazgeçilmez bir parçası haline gelmiştir. 2026 yılında Pest, Laravel topluluğunda standart test framework'ü olarak konumunu sağlamlaştırmış ve PHPUnit'in sunduğu tüm özellikleri daha okunabilir, daha az boilerplate kod ile sunmaktadır. Bu makalede Laravel projelerinde profesyonel düzeyde test yazma teknikleri, mocking stratejileri ve teknik mülakatlarda karşılaşılabilecek sorular ele alınmaktadır.
Test Driven Development (TDD) yaklaşımı, yazılım kalitesini artırmanın en etkili yollarından biridir. Laravel'in sunduğu test altyapısı, HTTP testlerinden veritabanı işlemlerine, queue job'larından mail gönderimlerine kadar uygulamanın her katmanını test etmeye olanak tanımaktadır. Pest framework'ü ile bu testler hem daha okunabilir hem de daha hızlı yazılabilir hale gelmektedir.
Bu rehberde feature testlerden unit testlere, facade mocking'den Mockery ile harici servis simülasyonuna kadar geniş bir yelpazede Laravel test pratikleri incelenmektedir. Ayrıca mimari testler ve mutation testing gibi ileri düzey konular da ele alınarak, teknik mülakatlara kapsamlı bir hazırlık sunulmaktadır.
Pest, PHPUnit üzerine inşa edilmiş modern bir test framework'üdür. Closure tabanlı syntax'ı sayesinde test dosyaları daha kısa ve okunabilir olmaktadır. it() ve expect() fonksiyonları ile doğal dil akışına yakın testler yazılabilmektedir. Higher-order testler, dataset'ler ve architecture testleri gibi özellikler Pest'i Laravel projeleri için ideal bir seçim haline getirmektedir. PHPUnit'in tüm assertion'ları kullanılabilirken, Pest'in expectation API'si daha ekspresif bir alternatif sunmaktadır.
Pest'i Laravel Projesinde Yapılandırma
Pest kurulumu sonrasında tests/Pest.php dosyası projenin test yapılandırmasını merkezi olarak yönetmektedir. Bu dosyada base test class'ı, trait'ler ve test dizinleri tanımlanmaktadır.
use Illuminate\Foundation\Testing\RefreshDatabase;
pest()
->extend(Tests\TestCase::class)
->use(RefreshDatabase::class)
->in('Feature');Bu yapılandırma ile tests/Feature dizinindeki tüm testler TestCase sınıfından extend edecek ve RefreshDatabase trait'ini kullanacaktır. Her test çalışmadan önce veritabanı migration'ları çalıştırılacak ve test sonrasında veritabanı sıfırlanacaktır. Bu yaklaşım, testler arasında veri izolasyonu sağlamaktadır.
Feature Testleri: HTTP Endpoint Doğrulama
Feature testleri, uygulamanın HTTP katmanını test etmek için kullanılmaktadır. Kullanıcı kayıt, giriş, CRUD işlemleri gibi endpoint'lerin beklenen davranışları bu testlerle doğrulanmaktadır.
use App\Models\User;
it('registers a new user with valid data', function () {
$response = $this->postJson('/api/register', [
'name' => 'Jane Doe',
'email' => 'jane@example.com',
'password' => 'SecurePass123!',
'password_confirmation' => 'SecurePass123!',
]);
$response->assertStatus(201)
->assertJsonStructure(['user' => ['id', 'name', 'email']]);
expect(User::where('email', 'jane@example.com')->exists())->toBeTrue();
});Bu testte kullanıcı kayıt endpoint'ine geçerli veriler gönderilmekte ve yanıtın 201 status kodu ile döndüğü doğrulanmaktadır. Ayrıca JSON yapısının beklenen formatta olduğu ve kullanıcının veritabanına kaydedildiği kontrol edilmektedir. postJson() metodu, Content-Type: application/json header'ı ile istek göndermektedir.
Unit Testler: İzole İş Mantığı Testi
Unit testler, tek bir sınıf veya metodun davranışını izole bir şekilde test etmek için kullanılmaktadır. Harici bağımlılıklar mock'lanarak, test edilen birimin doğru çalıştığı garanti altına alınmaktadır.
use App\Services\PriceCalculator;
describe('PriceCalculator', function () {
it('applies a percentage discount correctly', function () {
$calculator = new PriceCalculator();
// 20% off a 150.00 base price
$result = $calculator->applyDiscount(150.00, 20);
expect($result)->toBe(120.00);
});
it('rejects negative discount values', function () {
$calculator = new PriceCalculator();
expect(fn () => $calculator->applyDiscount(100.00, -5))
->toThrow(InvalidArgumentException::class);
});
});describe() bloğu, ilgili testleri gruplamak için kullanılmaktadır. İlk testte indirim hesaplamasının doğruluğu kontrol edilirken, ikinci testte negatif indirim değerlerinin exception fırlattığı doğrulanmaktadır. toThrow() expectation'ı, belirli bir exception türünün fırlatılmasını beklemektedir.
Laravel mülakatlarında başarılı olmaya hazır mısın?
İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.
Laravel Facade Mocking: Mail, Queue, Notifications
Laravel'in facade'ları, testlerde kolayca mock'lanabilmektedir. Mail::fake(), Queue::fake(), Notification::fake() gibi metodlar, gerçek işlemlerin yapılmasını engelleyerek test ortamında güvenli bir şekilde assertion yapılmasına olanak tanımaktadır.
use App\Models\Order;
use App\Models\User;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Queue;
use App\Mail\OrderConfirmation;
use App\Jobs\ProcessPayment;
it('dispatches payment job and sends confirmation email', function () {
// Fake both Mail and Queue facades
Mail::fake();
Queue::fake();
$user = User::factory()->create();
$order = Order::factory()->for($user)->create([
'total' => 99.99,
'status' => 'pending',
]);
// Act: confirm the order via HTTP
$this->actingAs($user)
->postJson("/api/orders/{$order->id}/confirm")
->assertOk();
// Assert: payment job was dispatched with correct amount
Queue::assertPushed(ProcessPayment::class, function ($job) use ($order) {
return $job->order->id === $order->id
&& $job->order->total === 99.99;
});
// Assert: confirmation email was sent to the user
Mail::assertSent(OrderConfirmation::class, function ($mail) use ($user) {
return $mail->hasTo($user->email);
});
});Bu testte sipariş onaylandığında hem ödeme job'ının queue'ya eklendiği hem de onay mailinin gönderildiği doğrulanmaktadır. Closure içinde yapılan kontroller, job ve mail'in doğru parametrelerle oluşturulduğunu garanti etmektedir. actingAs() metodu, belirli bir kullanıcı olarak authenticate edilmiş istek yapmayı sağlamaktadır.
Mockery ile İleri Düzey Mocking: Harici Servisler
Harici API'ler ve servisler, Mockery kütüphanesi ile mock'lanabilmektedir. Bu yaklaşım, testlerin harici servislere bağımlılığını ortadan kaldırarak hızlı ve güvenilir testler yazmayı mümkün kılmaktadır.
use App\Services\PaymentGateway;
use App\Services\StripeClient;
it('charges the customer through the payment gateway', function () {
// Create a mock of the Stripe client
$stripeClient = Mockery::mock(StripeClient::class);
$stripeClient->shouldReceive('charge')
->once()
->with('cus_abc123', 5000, 'usd')
->andReturn(['status' => 'succeeded', 'id' => 'ch_xyz']);
// Bind the mock in the container
$this->app->instance(StripeClient::class, $stripeClient);
$gateway = app(PaymentGateway::class);
$result = $gateway->processCharge('cus_abc123', 50.00);
expect($result['status'])->toBe('succeeded');
});Mockery ile oluşturulan mock nesne, shouldReceive() ile beklenen metod çağrılarını tanımlamaktadır. once() metodun tam olarak bir kez çağrılmasını, with() doğru parametrelerle çağrılmasını, andReturn() ise döndürülecek değeri belirlemektedir. Mock nesne Laravel container'a bind edilerek, dependency injection ile kullanılmaktadır.
Mimari Testler: Proje Kurallarını Zorunlu Kılma
Pest'in architecture testing özelliği, projedeki yapısal kuralların otomatik olarak denetlenmesini sağlamaktadır. Controller'ların doğrudan Eloquent kullanmaması, service sınıflarının final olması gibi kurallar test sürecinde kontrol edilebilmektedir.
arch('controllers do not use Eloquent directly')
->expect('App\Http\Controllers')
->not->toUse('Illuminate\Database\Eloquent');
arch('services are final classes')
->expect('App\Services')
->toBeFinal();
arch('no debugging functions in production code')
->expect(['dd', 'dump', 'var_dump', 'ray'])
->not->toBeUsed();Bu testler CI/CD pipeline'ında çalıştırılarak, kod review sürecinde gözden kaçabilecek yapısal sorunların önüne geçilmektedir. İlk test controller'ların repository veya service pattern kullanmasını zorunlu kılmakta, ikinci test service sınıflarının extend edilemeyeceğini garanti etmekte, üçüncü test ise debug fonksiyonlarının production kodunda bulunmamasını sağlamaktadır.
Pest ayrıca hazır preset'ler sunmaktadır:
arch()->preset()->laravel();
arch()->preset()->security();
arch()->preset()->php();Bu preset'ler Laravel best practice'lerini, güvenlik standartlarını ve PHP strict mode kurallarını otomatik olarak kontrol etmektedir.
Mutation Testing: Gerçek Test Kalitesini Değerlendirme
Code coverage yüksek olsa bile testlerin gerçekten etkili olup olmadığını mutation testing ile ölçmek mümkündür. Pest, Laravel ile entegre mutation testing desteği sunmaktadır.
# Run mutation testing on a specific class
php artisan test --mutate --class=App\\Services\\PriceCalculatorMutation testing, kaynak kodda küçük değişiklikler (mutasyonlar) yaparak testlerin bu değişiklikleri yakalayıp yakalamadığını kontrol etmektedir. Yakalanmayan mutasyonlar, testlerin yetersiz olduğunu göstermektedir.
// Example: this test has high coverage but low mutation score
it('calculates shipping cost', function () {
$cost = calculateShipping(weight: 5.0, zone: 'domestic');
// Only checks that the result is numeric
expect($cost)->toBeFloat();
});
// Improved: catches mutations by asserting the exact value
it('calculates domestic shipping for 5kg package', function () {
$cost = calculateShipping(weight: 5.0, zone: 'domestic');
// Exact assertion catches operator and value mutations
expect($cost)->toBe(12.50);
});İlk test sadece sonucun float olduğunu kontrol etmekte, bu nedenle hesaplamadaki hatalar fark edilememektedir. İkinci test ise kesin değeri kontrol ederek, operatör veya değer değişikliklerini yakalamaktadır. Mutation score, test suite'inin gerçek etkinliğini gösteren önemli bir metriktir.
Mülakatlar İçin Kapsamlı Test Senaryoları
Teknik mülakatlarda sıklıkla karşılaşılan senaryo, bir CRUD işleminin testini yazmaktır. Aşağıda makale yayınlama işleminin testi yer almaktadır:
use App\Models\Article;
use App\Models\User;
it('publishes a draft article and updates the timestamp', function () {
$author = User::factory()->create(['role' => 'editor']);
$article = Article::factory()
->for($author, 'author')
->draft()
->create(['title' => 'Testing Best Practices']);
$this->actingAs($author)
->patchJson("/api/articles/{$article->id}/publish")
->assertOk()
->assertJsonPath('data.status', 'published');
$article->refresh();
expect($article->status)->toBe('published')
->and($article->published_at)->not->toBeNull()
->and($article->published_at->isToday())->toBeTrue();
});Bu test, factory state'leri, ilişkili model oluşturma, HTTP assertion'ları ve chained expectation'ları bir arada kullanmaktadır. refresh() metodu veritabanından güncel veriyi çekmekte, assertJsonPath() ise nested JSON değerlerini kontrol etmektedir.
API authentication testleri de mülakatlarda sıkça sorulan konular arasındadır:
use App\Models\User;
describe('API Authentication', function () {
it('rejects unauthenticated requests with 401', function () {
$this->getJson('/api/profile')
->assertUnauthorized();
});
it('returns the authenticated user profile', function () {
$user = User::factory()->create([
'name' => 'John Doe',
'email' => 'john@example.com',
]);
$this->actingAs($user)
->getJson('/api/profile')
->assertOk()
->assertJson([
'data' => [
'name' => 'John Doe',
'email' => 'john@example.com',
],
]);
});
it('validates required fields on registration', function () {
$this->postJson('/api/register', [])
->assertUnprocessable()
->assertJsonValidationErrors(['name', 'email', 'password']);
});
});Bu test grubu authentication middleware'inin çalışmasını, başarılı login sonrası kullanıcı verilerinin döndürülmesini ve validation hatalarının doğru formatlanmasını kontrol etmektedir.
Pratik yapmaya başla!
Mülakat simülatörleri ve teknik testlerle bilgini test et.
Teknik Mülakat Soruları: Laravel Testing
Laravel testing konusunda teknik mülakatlarda karşılaşılabilecek sorular ve beklenen cevap yaklaşımları aşağıda sıralanmaktadır:
RefreshDatabase ve DatabaseTransactions arasındaki fark nedir?
RefreshDatabase her test öncesinde migration'ları çalıştırır ve veritabanını sıfırlar. DatabaseTransactions ise her testi bir transaction içinde çalıştırır ve test sonunda rollback yapar. RefreshDatabase daha yavaş ancak daha güvenilirdir; DatabaseTransactions ise seeded data ile çalışırken tercih edilebilir.
Pest'te higher-order test nedir?
Higher-order testler, test metodlarını doğrudan chain'leyerek yazmayı sağlar. Örneğin it('has dashboard')->get('/dashboard')->assertOk() şeklinde tek satırda test yazılabilir. Bu yaklaşım basit assertion'lar için kodu önemli ölçüde kısaltmaktadır.
Facade mocking ve dependency injection mock'lama arasındaki fark nedir?
Facade mocking Laravel'in built-in fake metodlarını kullanır ve gerçek implementasyonu tamamen bypass eder. DI mock'lama ise Mockery ile belirli metodların davranışını tanımlar ve container'a bind eder. Facade mocking daha basitken, DI mock'lama daha granüler kontrol sağlamaktadır.
Architecture testleri hangi durumlarda kullanılmalıdır?
Architecture testleri, ekip genelinde tutarlılığı sağlamak, best practice'leri zorlamak ve teknik borç birikimini önlemek için kullanılmalıdır. Özellikle büyük ekiplerde ve uzun ömürlü projelerde kritik öneme sahiptir.
Test coverage ile mutation score arasındaki ilişki nedir?
Test coverage kodun ne kadarının çalıştırıldığını gösterirken, mutation score testlerin ne kadar etkili olduğunu gösterir. Yüksek coverage düşük mutation score ile birlikte gelebilir; bu durum testlerin assertion kalitesinin düşük olduğunu göstermektedir.
Sonuç
Laravel uygulamalarında profesyonel düzeyde test yazmak, Pest framework'ü ile oldukça verimli hale gelmektedir. Feature testlerden unit testlere, facade mocking'den mimari testlere kadar Laravel'in sunduğu test altyapısı kapsamlı bir coverage sağlamaktadır. Mutation testing ile test kalitesi ölçülebilmekte, architecture testleri ile proje standartları zorlanabilmektedir.
Teknik mülakatlarda Laravel testing konusunda başarılı olmak için yalnızca syntax bilgisi yeterli değildir. Test stratejileri, mocking yaklaşımları, performans optimizasyonları ve best practice'ler hakkında derinlemesine bilgi sahibi olmak gerekmektedir. Bu makalede sunulan örnekler ve açıklamalar, hem günlük geliştirme pratiğinde hem de mülakat hazırlığında referans olarak kullanılabilecek niteliktedir.
Etiketler
Paylaş
İlgili makaleler

Laravel 12 (2026): Yeni Özellikler, Starter Kit'ler ve Mülakat Soruları
Laravel 12, React 19, Vue 3, Livewire 4 ve WorkOS AuthKit ile tamamen yeniden tasarlanmış starter kit'ler sunuyor. 2026 yılı için yeni özellikler, yükseltme rehberi ve teknik mülakat soruları.

2026 Yilinda En Cok Sorulan 25 Laravel ve PHP Mulakat Sorusu
Laravel mulakat sorulari: Service Container, Eloquent ORM, middleware, kuyruklar, guvenlik, test ve mimari desenler hakkinda 25 soru ve kod ornekleriyle kapsamli bir rehber.

Laravel Middleware Derinlemesine: Kimlik Dogrulama, Rate Limiting ve Ozel Middleware
Laravel middleware hakkinda kapsamli rehber - kimlik dogrulamadan rate limitinge, ozel middleware siniflari olusturmaya kadar. Pratik kod ornekleri ve uretim ortami desenleri.