# 2026'da Go ile Test: Birim Testleri, Mock'lar ve Teknik Mülakat Soruları > Standart kütüphane, tablo güdümlü testler, mock'lar ve mülakatçıların beklediği kalıplarla Go testlerinde ustalaşın. testify, gomock ve testing paketi ile pratik örnekler. - Published: 2026-08-24 - Updated: 2026-08-24 - Author: Anthony Fillion-Maillet - Tags: go, testing, unit-tests, mocks, interview - Reading time: 9 min --- Go'da test yazma, her Go kurulumunda bulunan ve herhangi bir harici bağımlılık gerektirmeyen standart `testing` paketine dayanır. Diğer dillerdeki framework'lerin aksine, Go'nun yaklaşımı sadeliği tercih eder: test dosyaları üretim koduyla yan yana bulunur, test fonksiyonları bir adlandırma kuralını takip eder ve `go test` komutu keşif ile yürütmeyi üstlenir. > **Mülakatçılar nelere bakıyor** > > Tablo güdümlü testler yazan, bağımlılık enjeksiyonu için arayüzler kullanan ve mock'lamanın ne zaman değer kattığını, ne zaman gereksiz karmaşıklık oluşturduğunu anlayan adaylar. ## testing Paketi ile Birim Testleri Yazma Her test dosyası `_test.go` ile biter ve test ettiği kodla aynı pakette bulunur. Test fonksiyonları `Test` ile başlar ve ardından büyük harfle bir isim gelir. `*testing.T` parametresi hata raporlama metodları sağlar. ```go // calculator_test.go package calculator import "testing" func TestAdd(t *testing.T) { result := Add(2, 3) if result != 5 { t.Errorf("Add(2, 3) = %d; want 5", result) } } ``` `go test ./...` çalıştırmak mevcut modüldeki tüm testleri yürütür. `-v` bayrağı her testin adını ve geçti/kaldı durumunu gösterir. ## Tablo Güdümlü Testler: Go Standardı Tablo güdümlü testler tekrarı azaltır ve yeni vakalar eklemeyi önemsiz kılar. Tablodaki her satır, girdiler ve beklenen çıktılarla bir senaryoyu temsil eder. Bu kalıp [Go standart kütüphanesinde](https://cs.opensource.google/go/go/+/refs/tags/go1.23.1:src/strings/strings_test.go) ve sektör genelindeki üretim kod tabanlarında görülür. ```go // validator_test.go package validator import "testing" func TestValidateEmail(t *testing.T) { tests := []struct { name string email string wantErr bool }{ {"valid email", "user@example.com", false}, {"missing at sign", "userexample.com", true}, {"empty string", "", true}, {"unicode local part", "user@例え.jp", false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateEmail(tt.email) if (err != nil) != tt.wantErr { t.Errorf("ValidateEmail(%q) error = %v, wantErr %v", tt.email, err, tt.wantErr) } }) } } ``` `t.Run` metodu bağımsız çalışan alt testler oluşturur. Başarısız alt testler, diğer vakaları durdurmadan hangi spesifik vakanın başarısız olduğunu raporlar. ## Arayüzler Aracılığıyla Bağımlılık Enjeksiyonu Go arayüzleri, harici sistemlere bağımlı kodun test edilmesini sağlar: veritabanları, HTTP istemcileri, dosya sistemleri. Kullanım noktasında minimal bir arayüz tanımlamak, gerçek implementasyonların test dublörleriyle değiştirilmesine olanak tanır. ```go // service.go package order // Repository defines the data access methods this service needs type Repository interface { FindByID(id string) (*Order, error) Save(order *Order) error } // Service handles order business logic type Service struct { repo Repository } // NewService creates a service with the given repository func NewService(repo Repository) *Service { return &Service{repo: repo} } // Process validates and saves an order func (s *Service) Process(order *Order) error { if order.Total <= 0 { return ErrInvalidTotal } return s.repo.Save(order) } ``` `Service`, `Repository`'yi karşılayan herhangi bir tipi kabul eder. Üretim kodu veritabanı destekli bir implementasyon geçirir. Testler bir mock veya stub geçirir. ## gomock ve mockgen ile Mock'lama [gomock](https://github.com/uber-go/mock) paketi, arayüz tanımlarından mock implementasyonları üretir. `mockgen` komutu kaynak dosyaları okur ve çağrıları kaydeden, yapılandırılmış değerler döndüren mock struct'ları üretir. ```bash # Generate mocks for the Repository interface mockgen -source=service.go -destination=mocks/repository_mock.go -package=mocks ``` Testlerde üretilen mock'u kullanma: ```go // service_test.go package order import ( "testing" "github.com/stretchr/testify/assert" "go.uber.org/mock/gomock" "yourmodule/order/mocks" ) func TestService_Process_SavesValidOrder(t *testing.T) { ctrl := gomock.NewController(t) mockRepo := mocks.NewMockRepository(ctrl) order := &Order{ID: "123", Total: 99.99} // Expect Save to be called once with this order, return nil mockRepo.EXPECT(). Save(order). Return(nil). Times(1) svc := NewService(mockRepo) err := svc.Process(order) assert.NoError(t, err) } func TestService_Process_RejectsZeroTotal(t *testing.T) { ctrl := gomock.NewController(t) mockRepo := mocks.NewMockRepository(ctrl) // No calls expected to repo since validation fails first svc := NewService(mockRepo) err := svc.Process(&Order{ID: "456", Total: 0}) assert.ErrorIs(t, err, ErrInvalidTotal) } ``` Mock, `Save`'in beklenen argümanla tam olarak bir kez çağrıldığını doğrular. Test edilen kod `Save`'i hiç çağırmazsa veya farklı argümanlarla çağırırsa, test başarısız olur. ## Assertion'lar ve Test Suite'leri için testify Kullanma [testify](https://github.com/stretchr/testify), manuel if kontrollerinden daha net hata mesajları üreten assertion fonksiyonları sağlar. `assert` paketi hatalardan sonra yürütmeye devam eder. `require` paketi testi hemen durdurur. ```go // user_test.go package user import ( "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestParseUser(t *testing.T) { input := `{"id": "u1", "name": "Alice"}` user, err := ParseUser(input) require.NoError(t, err, "parsing should not fail") assert.Equal(t, "u1", user.ID) assert.Equal(t, "Alice", user.Name) assert.Empty(t, user.Email, "email should default to empty") } ``` `require.NoError` çağrısı, ayrıştırma başarısız olursa testi durdurur ve sonraki assertion'larda nil pointer paniklerini önler. ## httptest ile HTTP Handler'larını Test Etme `net/http/httptest` paketi, handler çıktısını yakalamak için `ResponseRecorder` ve yerel bir test sunucusu çalıştırmak için `Server` sağlar. Çoğu birim testi, ağ yükünden kaçınmak için `ResponseRecorder` kullanır. ```go // handler_test.go package api import ( "net/http" "net/http/httptest" "testing" "github.com/stretchr/testify/assert" ) func TestHealthHandler(t *testing.T) { req := httptest.NewRequest(http.MethodGet, "/health", nil) rec := httptest.NewRecorder() HealthHandler(rec, req) assert.Equal(t, http.StatusOK, rec.Code) assert.JSONEq(t, `{"status": "ok"}`, rec.Body.String()) } ``` Harici servisleri çağıran handler'lar için bir mock istemci enjekte edin veya sahte bir backend oluşturmak için `httptest.NewServer` kullanın. ## Go Testleri Hakkında Yaygın Mülakat Soruları Mülakatçılar, gerçek kod tabanlarıyla deneyimi ortaya çıkaran sorularla test bilgisini değerlendirir. İşte hazırlıklı adayları ayırt eden kalıplar: **"Harici bir API çağıran bir fonksiyonu nasıl test edersiniz?"** HTTP istemcisi için bir arayüz tanımlayın, fonksiyona veya struct'a enjekte edin ve önceden belirlenmiş yanıtlar döndüren bir mock sağlayın. Bu, ağ çağrılarını ortadan kaldırır ve testleri deterministik yapar. **"Stub ile mock'u ne zaman kullanırsınız?"** Stub'lar, nasıl çağrıldıklarını doğrulamadan hazır yanıtlar döndürür. Mock'lar, belirli metodların belirli argümanlarla çağrıldığını doğrular. Dönüş değeri etkileşimden daha önemliyse stub kullanın. Etkileşimi doğrulamak testin amacıysa mock kullanın. **"Tablo güdümlü testler nedir ve Go neden bunları tercih eder?"** Tablo güdümlü testler, test vakalarını struct'ların slice'ında veri olarak tanımlar. Boilerplate'i azaltır, vaka eklemeyi önemsiz kılar ve `t.Run` ile okunabilir test çıktısı üretir. Kalıp, Go'nun akıllı soyutlamalar yerine açık, tekrarlayan kodu tercih etmesiyle uyumludur. **"Birden fazla testin paylaştığı test fixture'larını veya kurulumu nasıl yönetirsiniz?"** Paket düzeyinde kurulum ve temizlik için `TestMain` kullanın. İlgili testler arasında paylaşılan kurulum için yardımcı fonksiyonlar veya test suite'leri (testify'dan) kullanın. Testler arasında bağlantı oluşturan global durumdan kaçının. Bir Go mülakatına mı hazırlanıyorsunuz? [Go testing modülü](/technologies/go/interview-questions/testing) bu kalıpları pratik sorularla derinlemesine ele alır. ## Coverage ve Race Detection ile Testleri Çalıştırma `go test` komutu, test edilmemiş kod yollarını ve eşzamanlılık hatalarını ortaya çıkaran bayrakları kabul eder. ```bash # Run tests with coverage report go test -cover ./... # Generate HTML coverage visualization go test -coverprofile=coverage.out ./... go tool cover -html=coverage.out -o coverage.html # Detect race conditions (slower, but catches real bugs) go test -race ./... ``` Race detector bellek erişimlerini izler ve aynı değişkene eşzamanlı okuma ve yazmaları işaretler. CI'da testleri `-race` ile çalıştırmak, yalnızca belirli zamanlama altında ortaya çıkan hataları yakalar. ## Büyük Kod Tabanlarında Testleri Organize Etme Projeler büyüdükçe, test organizasyonu sürdürülebilirliği etkiler: - **Aynı paket testleri** (`package foo`) dışa aktarılmayan fonksiyonlara ve alanlara erişir. Dahili davranışı doğrulayan birim testleri için kullanın. - **Harici paket testleri** (`package foo_test`) paketi harici kod gibi içe aktarır. Entegrasyon testleri ve genel API'yi doğrulamak için kullanın. - **Testdata dizinleri** JSON dosyaları, golden output'lar veya seed veritabanları gibi fixture'ları saklar. Go bunları derleme sırasında yok sayar. - **Build tag'leri** birim testlerini harici sistemler gerektiren entegrasyon testlerinden ayırır. Bunları dahil etmek için `go test -tags=integration ./...` çalıştırın. Test dışında Go en iyi uygulamaları hakkında daha fazla bilgi için, goroutine'leri ve kanalları ele alan [eşzamanlılık kalıpları makalesi](/blog/go/go-concurrency-goroutines-channels) incelenebilir. ## Go Testi Hakkında Hatırlanması Gerekenler - `testing` paketi Go ile birlikte gelir ve harici bağımlılık gerektirmez - Tablo güdümlü testler tekrarı azaltır ve mülakatlarda beklenen kalıptır - Arayüzler bağımlılık enjeksiyonunu sağlar; implementasyonda değil kullanım noktasında tanımlayın - `gomock` arayüzlerden mock'lar üretir; `testify` daha temiz assertion'lar sağlar - `httptest.ResponseRecorder` ağ yükü olmadan handler çıktısını yakalar - `-race` bayrağı birim testlerinin aksi halde kaçırdığı eşzamanlılık hatalarını tespit eder - Coverage metrikleri dikkati yönlendirir ancak doğruluğu garanti etmez --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/tr/blog/go/go-testing-2026-unit-tests-mocks-interview