Birim Testleri Yazma: Jest ile Adım Adım Rehber ve Örnekler

Yazılım Test ve Hata Ayıklama

Birim Testleri Yazma: Jest ile Adım Adım Rehber ve Örnekler

Bu makale Jest kullanarak birim testleri yazma, mocking ve TDD uygulamalarını adım adım örneklerle açıklar.
Birim Testleri Yazma: Jest ile Adım Adım Rehber ve Örnekler

Giriş

Bu rehberde Jest ile birim testleri nasıl yazılır, mocking nasıl uygulanır ve Test-Driven Development (TDD) mantığıyla nasıl çalışılacağı adım adım göreceksiniz. Jest, test koşucusu ve assertion fonksiyonlarını bir arada sunan popüler bir çerçevedir; özellikle fonksiyon ve modül mock'lama yetenekleri testlerinizi izole etmenizi sağlar. Daha fazla detay için resmi Jest belgelerine bakabilirsiniz: Jest belgeleri.

Birim testleri nedir ve neden önemlidir?

Birim testleri, uygulamanın en küçük işlevsel parçalarını (fonksiyonlar, sınıflar, metotlar) izole ederek doğrulamak için yazılır. Bu yaklaşım hataları erken yakalamaya, regresyonları azaltmaya ve bakım maliyetini düşürmeye yardımcı olur. AWS tarafından birim testlerinin yazılımın güvenilirliğini artırdığı vurgulanmaktadır: Birim Testi Nedir? — AWS.

  • Daha erken hata tespiti ve daha güvenli refaktör.
  • Dokümantasyon işlevi: testler kodun nasıl çalışması gerektiğini gösterir.
  • Otomatik testler CI/CD pipeline'larında hızlı geri bildirim sağlar.

Jest ile kuruluma hızlı başlangıç

Yeni bir Node.js projesinde Jest'i şu adımlarla kurabilirsiniz:

  • 1) Projeyi başlatın:
    npm init -y
  • 2) Jest'i geliştirme bağımlılığı olarak ekleyin:
    npm install --save-dev jest
  • 3) package.json içinde bir test script'i oluşturun:
    "scripts": { "test": "jest" }

Bu adımların ardından npm test veya npx jest ile testleri çalıştırabilirsiniz.

Basit birim testi örneği (adım adım)

Aşağıda küçük bir örnek proje yapısı ve test örneği yer alır. Amaç önce basit bir fonksiyonu test etmek, sonra kodu uygulamaktır.

  • src/add.js — toplama fonksiyonu
  • tests/add.test.js — add fonksiyonu için test

src/add.js
function add(a, b) {
return a + b;
}
module.exports = { add };

tests/add.test.js
const { add } = require('../src/add');
describe('add', () => {
test('İki sayıyı toplar', () => {
expect(add(1, 2)).toBe(3);
});
});

Yukarıdaki testte describe testi gruplar; test (veya eşdeğeri it) spesifik bir beklentiyi tanımlar. expect ile assertion yapılır. Jest belgelerinde bu yapıların kullanımı ayrıntılı açıklanmıştır: Jest mock fonksiyonları ve temel kullanım.

Mocking: Dış bağımlılıkları izole etme

Gerçek HTTP çağrıları, veritabanları veya zamanlayıcılar gibi dış kaynakları testlerde kullanmak testi yavaşlatır ve kararsız hale getirebilir. Mocking ile bu bağımlılıklar izole edilir, böylece testler deterministik olur. Jest, jest.fn() ve jest.mock() gibi araçlar sunar (daha fazla bilgi: Jest docs).

jest.fn() örneği (spy / callback)

Aşağıda bir callback'in çağrılma sayısını doğrulayan örnek var.

src/processor.js
function process(items, cb) {
items.forEach(item => cb(item));
}
module.exports = { process };

tests/processor.test.js
const { process } = require('../src/processor');
test('callback her öğe için çağrılır', () => {
const cb = jest.fn();
process([1, 2], cb);
expect(cb).toHaveBeenCalledTimes(2);
expect(cb).toHaveBeenCalledWith(1);
});

jest.mock() ile modül mocklama

Bir modülde gerçek HTTP çağrısı yapan fonksiyonları mocklamak için jest.mock() kullanabilirsiniz:

src/api.js
module.exports = { fetchUser: async (id) => { /* gerçek HTTP çağrısı */ } };

src/service.js
const api = require('./api');
async function getUserName(id) {
const user = await api.fetchUser(id);
return user.name;
}
module.exports = { getUserName };

tests/service.test.js
jest.mock('../src/api', () => ({
fetchUser: jest.fn(),
}));
const { getUserName } = require('../src/service');
const api = require('../src/api');
test('getUserName API yanıtından adı döndürür', async () => {
api.fetchUser.mockResolvedValue({ name: 'Alice' });
const name = await getUserName(1);
expect(name).toBe('Alice');
expect(api.fetchUser).toHaveBeenCalledWith(1);
});

TDD ile Jest: Test-First yaklaşımı

TDD (Test-Driven Development) temel olarak üç adımı tekrar eder: Failing Test (önce bir test yaz), Make It Pass (en az kod ile testi geçecek şekilde uygula), Refactor (temizle). Jest, hızlı çalışması ve kolay mocking destekleriyle TDD akışlarını destekler. Resmi belgelerde Jest'in test ve mock yetenekleri TDD ile uyumlu olarak açıklanmıştır: Jest mock fonksiyonları.

  • Adım 1: Testi yazın ve çalıştırın — testin başarısız olduğunu görün.
  • Adım 2: Minimum kodu yazarak testi geçirin.
  • Adım 3: Kodunuzu temizleyin ve yeniden çalıştırın.

İyi test yazma pratikleri

  • Testleri küçük ve tek sorumluluklu tutun: Bir test bir davranışı doğrulamalı.
  • Test isimlendirmesi açıklayıcı olsun: Ne beklendiğini kısa ve net yazın.
  • Harici bağımlılıkları mocklayın veya izole edin (ör. HTTP, DB, filesystem).
  • Aynı setup/teardown kodunu beforeEach ve afterEach ile yönetin.
  • Flaky (kararsız) testlerden kaçının — eşzamansız kodlarda zamanlama kaynaklı hatalara dikkat edin.
  • Test sonuçlarını CI'de çalıştırın; otomatik geri bildirim uygulayın.

Sık yapılan hatalar ve çözümleri

  • Gerçek ağ çağrıları kullanmak: Mocklayın veya local stub kullanın.
  • Büyük fixture'lar: Testi yavaşlatır; küçük, hedeflenmiş veriler kullanın.
  • Çok fazla bağımlılık: Testi tekil tutmak için dış bağımlılıkları azaltın.

Adım adım kontrol listesi

  • Proje kurulumu: jest kurulu mu? test script var mı?
  • Her fonksiyon için en az bir mutlu yol (happy path) testi yazın.
  • Sınır durumlar ve hata yolunu test edin.
  • Dış bağımlılıklar mocklandı mı?
  • Test isimleri açıklayıcı mı?
  • Testler CI'de stabil çalışıyor mu?

Kaynaklar ve ileri okuma

Bu rehberde verdiğim örnekler eğitim amaçlıdır; gerçek projelerde ortam (ESM/CJS, bundler, transpiler) farklılıkları nedeniyle ek yapılandırma gerekebilir. Yukarıdaki Jest ve AWS belgeleri, temel kavramları doğrulamak için başvurabileceğiniz resmi kaynaklardır.