{"id":31984,"date":"2025-10-16T10:01:25","date_gmt":"2025-10-16T07:01:25","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/"},"modified":"2025-10-16T10:01:25","modified_gmt":"2025-10-16T07:01:25","slug":"jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/","title":{"rendered":"Jest.spyOn: Birim Testleriniz \u0130\u00e7in Kapsaml\u0131 K\u0131lavuz"},"content":{"rendered":"<p><body><\/p>\n<p>Modern JavaScript uygulamalar\u0131nda kod kalitesi ve g\u00fcvenilirli\u011fi, birim testleriyle ba\u015flar. Peki, d\u0131\u015f ba\u011f\u0131ml\u0131l\u0131klar\u0131 olan veya yan etkiler \u00fcreten fonksiyonlar\u0131 test ederken ne yapmal\u0131s\u0131n\u0131z? Jest.spyOn, bu zorluklar\u0131n \u00fcstesinden gelerek testlerinizi daha izole ve y\u00f6netilebilir hale getirmenizi sa\u011flar. Bu kapsaml\u0131 k\u0131lavuzda, Jest.spyOn&#8217;\u0131n ne oldu\u011funu, nas\u0131l kullan\u0131ld\u0131\u011f\u0131n\u0131 ve birim test stratejinizi nas\u0131l d\u00f6n\u00fc\u015ft\u00fcrece\u011fini detaylar\u0131yla \u00f6\u011freneceksiniz.<\/p>\n<p>Yaz\u0131l\u0131m geli\u015ftirme s\u00fcre\u00e7lerinde, \u00f6zellikle de karma\u015f\u0131k ve mod\u00fcler uygulamalarda, birim testleri (unit tests) kritik bir rol oynar. Bir birimin (fonksiyon, metod, s\u0131n\u0131f) beklenen \u015fekilde \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 do\u011frulamak i\u00e7in yaz\u0131lan bu testler, kodunuzun g\u00fcvenilirli\u011fini art\u0131r\u0131r ve gelecekteki de\u011fi\u015fikliklerin mevcut i\u015flevselli\u011fi bozmas\u0131n\u0131 engeller. Ancak, ger\u00e7ek d\u00fcnyadaki bir\u00e7ok fonksiyon, kendi ba\u015f\u0131na izole bir \u015fekilde \u00e7al\u0131\u015fmaz; veritabanlar\u0131na, d\u0131\u015f API&#8217;lere, dosya sistemlerine veya di\u011fer mod\u00fcllere ba\u011f\u0131ml\u0131d\u0131rlar. \u0130\u015fte tam da bu noktada Jest.spyOn gibi ara\u00e7lar devreye girer ve test etme s\u00fcrecini k\u00f6kten de\u011fi\u015ftirir.<\/p>\n<p>Bir fonksiyonun d\u0131\u015f ba\u011f\u0131ml\u0131l\u0131klar\u0131 oldu\u011funda, bu ba\u011f\u0131ml\u0131l\u0131klar\u0131n ger\u00e7ek implementasyonlar\u0131yla test yapmak birka\u00e7 soruna yol a\u00e7abilir. \u00d6ncelikle, testler yava\u015flar. Her test ko\u015fuldu\u011funda bir veritaban\u0131 ba\u011flant\u0131s\u0131 kurmak, bir API \u00e7a\u011fr\u0131s\u0131 yapmak veya bir dosyay\u0131 okumak, test s\u00fcresini uzat\u0131r ve geli\u015ftirici deneyimini olumsuz etkiler. \u0130kincisi, testler karars\u0131z hale gelir. D\u0131\u015f servislerdeki gecikmeler, a\u011f hatalar\u0131 veya veritaban\u0131 de\u011fi\u015fiklikleri, kodunuzda hi\u00e7bir hata olmamas\u0131na ra\u011fmen testlerin ba\u015far\u0131s\u0131z olmas\u0131na neden olabilir. Bu duruma &#8220;flaky tests&#8221; denir ve geli\u015ftiricilerin testlere olan g\u00fcvenini sarsar. \u00dc\u00e7\u00fcnc\u00fcs\u00fc, birim testi prensiplerine ayk\u0131r\u0131d\u0131r. Birim testlerinin temel amac\u0131, ilgili birimi izole bir \u015fekilde test etmektir. Ba\u011f\u0131ml\u0131l\u0131klar\u0131n ger\u00e7ek implementasyonlar\u0131yla test yapmak, asl\u0131nda entegrasyon testi benzeri bir senaryo yarat\u0131r ve birimin kendi mant\u0131\u011f\u0131ndan ziyade ba\u011f\u0131ml\u0131l\u0131klar\u0131n davran\u0131\u015flar\u0131n\u0131 da test etmeye ba\u015flars\u0131n\u0131z. Bu da hata tespiti ve hata ay\u0131klama s\u00fcre\u00e7lerini zorla\u015ft\u0131r\u0131r.<\/p>\n<p>Jest.spyOn, tam da bu sorunlar\u0131 \u00e7\u00f6zmek i\u00e7in tasarlanm\u0131\u015f g\u00fc\u00e7l\u00fc bir Jest arac\u0131d\u0131r. Bir objenin mevcut bir metodunu &#8220;casuslaman\u0131za&#8221; (spy on) olanak tan\u0131r. Yani, metodun orijinal implementasyonunu korurken, o metoda yap\u0131lan \u00e7a\u011fr\u0131lar\u0131 izleyebilir, hangi arg\u00fcmanlarla \u00e7a\u011fr\u0131ld\u0131\u011f\u0131n\u0131 g\u00f6rebilir, ka\u00e7 kez \u00e7a\u011fr\u0131ld\u0131\u011f\u0131n\u0131 sayabilir ve hatta d\u00f6n\u00fc\u015f de\u011ferini veya davran\u0131\u015f\u0131n\u0131 ge\u00e7ici olarak de\u011fi\u015ftirebilirsiniz. Bu yetenek, bir fonksiyonun d\u0131\u015f ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 izole etmenin ve test ortam\u0131nda kontrol edilebilir hale getirmenin anahtar\u0131d\u0131r. B\u00f6ylece, testleriniz daha h\u0131zl\u0131, daha g\u00fcvenilir ve daha izole olur. Metodun yan etkilerini, yani veritaban\u0131na yazma veya bir HTTP iste\u011fi g\u00f6nderme gibi i\u015flemleri, test ortam\u0131nda ger\u00e7ekte ger\u00e7ekle\u015fmeden sim\u00fcle edebilirsiniz. Bu sayede, odak noktan\u0131z sadece test etti\u011finiz birimin kendi mant\u0131\u011f\u0131na kayar, d\u0131\u015f etkenlerden etkilenmezsiniz. \u00d6zellikle karma\u015f\u0131k sistemlerde, her bir mod\u00fcl\u00fcn ayr\u0131 ayr\u0131 test edilebilir olmas\u0131, genel kod kalitesini \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131r\u0131r ve hata ay\u0131klama s\u00fcre\u00e7lerini basitle\u015ftirir. K\u0131sacas\u0131, Jest.spyOn birim testlerinizi daha anlaml\u0131, daha h\u0131zl\u0131 ve daha g\u00fcvenilir hale getiren vazge\u00e7ilmez bir ara\u00e7t\u0131r. Bu sayede geli\u015ftiriciler, kodlar\u0131n\u0131n beklenen \u015fekilde \u00e7al\u0131\u015ft\u0131\u011f\u0131ndan emin olabilir ve projeye g\u00fcvenle devam edebilirler.<\/p>\n<h2>Jest.spyOn Temelleri: Nas\u0131l \u00c7al\u0131\u015f\u0131r ve Neler Sunar?<\/h2>\n<p>Jest.spyOn, bir objenin zaten var olan bir metodunu izlemek ve\/veya ge\u00e7ici olarak de\u011fi\u015ftirmek i\u00e7in kullan\u0131lan \u00f6zel bir fonksiyonudur. Temel olarak, bir casus (spy) olu\u015fturarak, metodun \u00e7a\u011fr\u0131lma durumunu (ka\u00e7 kez \u00e7a\u011fr\u0131ld\u0131, hangi arg\u00fcmanlarla \u00e7a\u011fr\u0131ld\u0131, ne d\u00f6nd\u00fcrd\u00fc) kaydedersiniz. Ancak bunu yaparken, metodun orijinal implementasyonunu varsay\u0131lan olarak korursunuz. Bu, Jest.fn() ile olan temel farklar\u0131ndan biridir; Jest.fn() s\u0131f\u0131rdan sahte bir fonksiyon olu\u015ftururken, Jest.spyOn var olan bir metodun \u00fczerine bir &#8220;dinleyici&#8221; yerle\u015ftirir. Bu \u00f6zellik, \u00f6zellikle bir mod\u00fcl\u00fcn kendi i\u00e7inde ba\u015fka bir metodunu \u00e7a\u011f\u0131rd\u0131\u011f\u0131 senaryolarda veya d\u0131\u015f bir ba\u011f\u0131ml\u0131l\u0131\u011f\u0131n belirli bir metodunun davran\u0131\u015f\u0131n\u0131 izlemek istedi\u011finizde \u00e7ok de\u011ferli hale gelir.<\/p>\n<p>Jest.spyOn&#8217;\u0131n temel s\u00f6zdizimi olduk\u00e7a basittir: <code>jest.spyOn(object, methodName)<\/code>. Burada <code>object<\/code>, \u00fczerinde metodun bulundu\u011fu nesne, <code>methodName<\/code> ise casuslamak istedi\u011finiz metodun ad\u0131d\u0131r (string olarak). Bu fonksiyonu \u00e7a\u011f\u0131rd\u0131\u011f\u0131n\u0131zda, size \u00f6zel bir &#8220;jest mock function&#8221; d\u00f6nd\u00fcr\u00fcr. Bu mock fonksiyon, \u00e7a\u011fr\u0131 ge\u00e7mi\u015fini izleme yetene\u011fine sahip olmas\u0131n\u0131n yan\u0131 s\u0131ra, metodun davran\u0131\u015f\u0131n\u0131 ge\u00e7ici olarak de\u011fi\u015ftirmenize olanak tan\u0131yan \u00e7e\u015fitli yard\u0131mc\u0131 metotlara da sahiptir.<\/p>\n<p>\u0130\u015fte Jest.spyOn ile birlikte s\u0131k\u00e7a kullan\u0131lan baz\u0131 yard\u0131mc\u0131 metotlar ve ne i\u015fe yarad\u0131klar\u0131:<\/p>\n<ul>\n<li>\n<pre><code>.mockReturnValue(value)<\/pre>\n<p><\/code>: Casuslad\u0131\u011f\u0131n\u0131z metodun her \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda belirli bir de\u011fer d\u00f6nd\u00fcrmesini sa\u011flar. Metodun orijinal implementasyonu bu durumda \u00e7al\u0131\u015fmaz. \u00d6rne\u011fin, bir API \u00e7a\u011fr\u0131s\u0131n\u0131n her zaman belirli bir ba\u015far\u0131 yan\u0131t\u0131 d\u00f6nd\u00fcrmesini sim\u00fcle etmek isteyebilirsiniz.\n    <\/li>\n<li>\n<pre><code>.mockImplementation((...args) => { ... })<\/pre>\n<p><\/code>: Metodun orijinal implementasyonunu tamamen \u00f6zel bir fonksiyon ile de\u011fi\u015ftirir. Bu, daha karma\u015f\u0131k davran\u0131\u015flar\u0131 (\u00f6rne\u011fin, arg\u00fcmanlara ba\u011fl\u0131 olarak farkl\u0131 de\u011ferler d\u00f6nd\u00fcrme) sim\u00fcle etmek i\u00e7in idealdir.\n    <\/li>\n<li>\n<pre><code>.mockResolvedValue(value)<\/pre>\n<p><\/code>: Asenkron metotlar (Promise d\u00f6nd\u00fcrenler) i\u00e7in kullan\u0131l\u0131r. Metodun ba\u015far\u0131l\u0131 bir \u015fekilde \u00e7\u00f6z\u00fcmlenmesini (resolve) ve belirli bir de\u011fer d\u00f6nd\u00fcrmesini sa\u011flar. API \u00e7a\u011fr\u0131lar\u0131n\u0131 veya veritaban\u0131 i\u015flemlerini taklit etmek i\u00e7in vazge\u00e7ilmezdir.\n    <\/li>\n<li>\n<pre><code>.mockRejectedValue(error)<\/pre>\n<p><\/code>: Yine asenkron metotlar i\u00e7in kullan\u0131l\u0131r, ancak metodun bir Promise hatas\u0131yla reddedilmesini (reject) sim\u00fcle eder. Hata senaryolar\u0131n\u0131 test etmek i\u00e7in kritiktir.\n    <\/li>\n<li>\n<pre><code>.and.callThrough()<\/pre>\n<p><\/code>: Bu \u00f6zel bir durumdur. E\u011fer casuslad\u0131ktan sonra metodun orijinal implementasyonunun yine de \u00e7al\u0131\u015fmas\u0131n\u0131 istiyorsan\u0131z bunu kullan\u0131rs\u0131n\u0131z. Varsay\u0131lan davran\u0131\u015f budur ancak bazen ba\u015fka bir .mock* metodu kulland\u0131ktan sonra geri d\u00f6nmek i\u00e7in a\u00e7\u0131k\u00e7a belirtmek gerekebilir.\n    <\/li>\n<li>\n<pre><code>.and.returnValue(value)<\/pre>\n<p><\/code>: .mockReturnValue() ile benzerdir ancak daha \u00e7ok Jest'in eski versiyonlar\u0131nda veya belirli zincirleme senaryolar\u0131nda g\u00f6r\u00fclebilir.\n    <\/li>\n<\/ul>\n<p>Jest.spyOn'\u0131n g\u00fcc\u00fc, hem \u00e7a\u011fr\u0131lar\u0131 izleyebilme hem de metodun davran\u0131\u015f\u0131n\u0131 kontrol edebilme yetene\u011finden gelir. \u00d6rne\u011fin, bir veritaban\u0131 servisinin <code>save()<\/code> metodunu casuslayarak, bu metodun ger\u00e7ekten veritaban\u0131na yaz\u0131p yazmad\u0131\u011f\u0131n\u0131 de\u011fil, sadece do\u011fru arg\u00fcmanlarla \u00e7a\u011fr\u0131l\u0131p \u00e7a\u011fr\u0131lmad\u0131\u011f\u0131n\u0131 test edebilirsiniz. Ard\u0131ndan, <code>.mockResolvedValue({ id: 1 })<\/code> ile sahte bir d\u00f6n\u00fc\u015f de\u011feri sa\u011flayarak, veritaban\u0131 i\u015fleminin ba\u015far\u0131l\u0131 oldu\u011funu sim\u00fcle edebilirsiniz. Bu \u015fekilde, testleriniz h\u0131zlan\u0131r ve d\u0131\u015f etkenlerden ar\u0131n\u0131r. Ayr\u0131ca, her testin sonunda casuslad\u0131\u011f\u0131n\u0131z metodu orijinal haline d\u00f6nd\u00fcrmek i\u00e7in <code>.mockRestore()<\/code> metodunu kullanmak iyi bir uygulamad\u0131r. Bu, testler aras\u0131nda \"s\u0131z\u0131nt\u0131\" olmas\u0131n\u0131 engeller ve test ortam\u0131n\u0131n temiz kalmas\u0131n\u0131 sa\u011flar. K\u0131sacas\u0131, Jest.spyOn ile kodunuzun ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 soyutlayarak daha g\u00fcvenilir ve s\u00fcrd\u00fcr\u00fclebilir bir test altyap\u0131s\u0131 kurabilirsiniz. Bu esneklik, \u00f6zellikle b\u00fcy\u00fck ve karma\u015f\u0131k projelerde, birim testlerinin etkinli\u011fini ve de\u011ferini katlayarak art\u0131r\u0131r.<\/p>\n<h3>\u0130lk Ad\u0131mlar: Basit Bir Metodu Nas\u0131l Casuslars\u0131n\u0131z?<\/h3>\n<p>Jest.spyOn ile \u00e7al\u0131\u015fmaya ba\u015flamak, d\u00fc\u015f\u00fcnd\u00fc\u011f\u00fcn\u00fczden \u00e7ok daha kolayd\u0131r. Basit bir \u00f6rnek \u00fczerinden bu g\u00fc\u00e7l\u00fc arac\u0131n nas\u0131l kullan\u0131ld\u0131\u011f\u0131n\u0131 ad\u0131m ad\u0131m inceleyelim. Diyelim ki, basit matematiksel i\u015flemler yapan bir <code>calculator<\/code> objemiz var ve bu objenin <code>add<\/code> metodunu casuslamak istiyoruz. Amac\u0131m\u0131z, <code>add<\/code> metodunun belirli arg\u00fcmanlarla \u00e7a\u011fr\u0131l\u0131p \u00e7a\u011fr\u0131lmad\u0131\u011f\u0131n\u0131 kontrol etmek ve belki de ge\u00e7ici olarak farkl\u0131 bir de\u011fer d\u00f6nd\u00fcrmesini sa\u011flamak.<\/p>\n<p>\u00d6ncelikle, casuslayaca\u011f\u0131m\u0131z objeyi tan\u0131mlayal\u0131m. Bir <code>calculator.js<\/code> dosyam\u0131z oldu\u011funu varsayal\u0131m:<\/p>\n<pre><code>\n\/\/ calculator.js\nconst calculator = {\n  add: (a, b) => a + b,\n  subtract: (a, b) => a - b,\n  multiply: (a, b) => a * b,\n};\n\nmodule.exports = calculator;\n  <\/pre>\n<p><\/code><\/p>\n<p>\u015eimdi bu <code>calculator<\/code> objesini test etmek i\u00e7in bir <code>calculator.test.js<\/code> dosyas\u0131 olu\u015ftural\u0131m. Test dosyam\u0131zda Jest.spyOn kullanarak <code>add<\/code> metodunu nas\u0131l casuslayaca\u011f\u0131m\u0131z\u0131 g\u00f6relim:<\/p>\n<pre><code>\n\/\/ calculator.test.js\nconst calculator = require('.\/calculator');\n\ndescribe('Calculator', () => {\n  let addSpy;\n\n  \/\/ Her testten \u00f6nce casusu s\u0131f\u0131rla veya yeniden olu\u015ftur\n  beforeEach(() => {\n    \/\/ calculator objesinin 'add' metodunu casusla\n    addSpy = jest.spyOn(calculator, 'add');\n  });\n\n  \/\/ Her testten sonra casusu orijinal haline d\u00f6nd\u00fcr\n  afterEach(() => {\n    addSpy.mockRestore(); \/\/ Bu sat\u0131r \u00e7ok \u00f6nemlidir!\n  });\n\n  test('add metodu do\u011fru arg\u00fcmanlarla \u00e7a\u011fr\u0131lmal\u0131 ve do\u011fru sonu\u00e7 d\u00f6nmeli', () => {\n    \/\/ Casuslanan metodu \u00e7a\u011f\u0131r\n    const result = calculator.add(2, 3);\n\n    \/\/ add metodunun \u00e7a\u011fr\u0131ld\u0131\u011f\u0131n\u0131 kontrol et\n    expect(addSpy).toHaveBeenCalledTimes(1);\n    expect(addSpy).toHaveBeenCalledWith(2, 3);\n\n    \/\/ Orijinal implementasyonun \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 do\u011frula\n    expect(result).toBe(5);\n  });\n\n  test('add metodunu farkl\u0131 bir de\u011fer d\u00f6nd\u00fcrecek \u015fekilde mock edebiliriz', () => {\n    \/\/ add metodunun her \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda 100 d\u00f6nd\u00fcrmesini sa\u011fla\n    addSpy.mockReturnValue(100);\n\n    const result1 = calculator.add(5, 5); \/\/ Orijinalde 10 d\u00f6necekti\n    const result2 = calculator.add(10, 20); \/\/ Orijinalde 30 d\u00f6necekti\n\n    expect(result1).toBe(100);\n    expect(result2).toBe(100);\n\n    expect(addSpy).toHaveBeenCalledTimes(2); \/\/ \u0130ki kez \u00e7a\u011fr\u0131ld\u0131\n    expect(addSpy).toHaveBeenCalledWith(5, 5); \/\/ \u0130lk \u00e7a\u011fr\u0131 kontrol\u00fc\n    expect(addSpy).toHaveBeenCalledWith(10, 20); \/\/ \u0130kinci \u00e7a\u011fr\u0131 kontrol\u00fc\n  });\n\n  test('add metodunun implementasyonunu de\u011fi\u015ftirebiliriz', () => {\n    \/\/ add metodunu \u00f6zel bir implementasyon ile de\u011fi\u015ftir\n    addSpy.mockImplementation((a, b) => a * b); \/\/ \u015eimdi toplama yerine \u00e7arpma yapacak\n\n    const result = calculator.add(2, 3); \/\/ Orijinalde 5 d\u00f6necekti\n\n    expect(result).toBe(6); \/\/ \u00c7arpma sonucunu bekliyoruz\n    expect(addSpy).toHaveBeenCalledTimes(1);\n    expect(addSpy).toHaveBeenCalledWith(2, 3);\n  });\n});\n  <\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte g\u00f6rd\u00fc\u011f\u00fcn\u00fcz gibi, <code>jest.spyOn(calculator, 'add')<\/code> ile <code>calculator<\/code> objesinin <code>add<\/code> metodunu ba\u015far\u0131yla casuslad\u0131k. <code>beforeEach<\/code> ve <code>afterEach<\/code> bloklar\u0131, her testten \u00f6nce casusu temizleyip yeniden olu\u015fturarak testler aras\u0131 ba\u011f\u0131ms\u0131zl\u0131\u011f\u0131 sa\u011flamak i\u00e7in kritik \u00f6neme sahiptir. \u00d6zellikle <code>addSpy.mockRestore()<\/code> \u00e7a\u011fr\u0131s\u0131, her test bitti\u011finde casuslanan metodun orijinal implementasyonuna geri d\u00f6nmesini garanti eder. Bu olmadan, bir testte yap\u0131lan mock i\u015flemi di\u011fer testleri etkileyebilir ve \"side effects\" denen istenmeyen durumlara yol a\u00e7abilir. \u0130lk test, metodun orijinal davran\u0131\u015f\u0131n\u0131 korudu\u011funu ve \u00e7a\u011fr\u0131 bilgilerini ba\u015far\u0131yla yakalad\u0131\u011f\u0131n\u0131 g\u00f6sterirken, ikinci test <code>.mockReturnValue()<\/code> ile metodun sahte bir de\u011fer d\u00f6nd\u00fcrmesini sa\u011flad\u0131. \u00dc\u00e7\u00fcnc\u00fc test ise <code>.mockImplementation()<\/code> ile metodun tamamen farkl\u0131 bir i\u015flev g\u00f6rmesini sa\u011flayarak esnekli\u011fini ortaya koydu. Bu basit ad\u0131mlarla, herhangi bir objenin metodunu izleyebilir, davran\u0131\u015f\u0131n\u0131 de\u011fi\u015ftirebilir ve testlerinizi \u00e7ok daha kontrol edilebilir bir hale getirebilirsiniz. Bu yetenek, birim testlerinizi yazarken size muazzam bir esneklik ve g\u00fc\u00e7 katacakt\u0131r.<\/p>\n<div class=\"expert-tip\">\n    Uzman \u0130pucu: Jest.spyOn kullan\u0131rken <\/p>\n<pre><code>.mockRestore()<\/pre>\n<p><\/code> veya <\/p>\n<pre><code>jest.clearAllMocks()<\/pre>\n<p><\/code> \/ <\/p>\n<pre><code>jest.restoreAllMocks()<\/pre>\n<p><\/code> gibi temizlik fonksiyonlar\u0131n\u0131 <\/p>\n<pre><code>afterEach<\/pre>\n<p><\/code> blo\u011funda kullanmay\u0131 asla unutmay\u0131n. Aksi takdirde, bir testteki mock i\u015flemi di\u011fer testleri etkileyebilir ve yanl\u0131\u015f pozitif veya negatif sonu\u00e7lara yol a\u00e7abilir. Bu, test s\u00fcitinizin kararl\u0131l\u0131\u011f\u0131 i\u00e7in hayati \u00f6neme sahiptir.\n  <\/div>\n<h2>Ger\u00e7ek D\u00fcnya Senaryolar\u0131: Jest.spyOn ile Karma\u015f\u0131k Ba\u011f\u0131ml\u0131l\u0131klar\u0131 Y\u00f6netme<\/h2>\n<p>Jest.spyOn'\u0131n ger\u00e7ek g\u00fcc\u00fc, karma\u015f\u0131k uygulamalardaki d\u0131\u015f ba\u011f\u0131ml\u0131l\u0131klar\u0131 y\u00f6netme ve izole etme yetene\u011finde yatar. \u00dcretim ortam\u0131nda, bir fonksiyonun bir veritaban\u0131 servisiyle etkile\u015fim kurmas\u0131, d\u0131\u015f bir API'ye istek g\u00f6ndermesi veya bir dosya sistemine yazma i\u015flemi yapmas\u0131 olduk\u00e7a yayg\u0131nd\u0131r. Bu t\u00fcr ba\u011f\u0131ml\u0131l\u0131klar\u0131 i\u00e7eren fonksiyonlar\u0131 do\u011frudan test etmek, yukar\u0131da bahsedildi\u011fi gibi yava\u015f, karars\u0131z ve g\u00fcvenilmez testlere yol a\u00e7abilir. Jest.spyOn, bu senaryolarda devreye girerek testlerinizi kontrol edilebilir ve verimli hale getirir. \u015eimdi, birka\u00e7 ger\u00e7ek d\u00fcnya senaryosu \u00fczerinden Jest.spyOn kullan\u0131m\u0131n\u0131 inceleyelim.<\/p>\n<h3>Senaryo 1: D\u0131\u015f API \u00c7a\u011fr\u0131s\u0131n\u0131 Casuslama<\/h3>\n<p>Diyelim ki, kullan\u0131c\u0131 bilgilerini almak i\u00e7in d\u0131\u015f bir API'ye istek g\u00f6nderen bir servisimiz var. Bu servisin testlerini yazarken, her seferinde ger\u00e7ek API'ye istek g\u00f6ndermek istemeyiz. Hem yava\u015f olur hem de a\u011f ba\u011flant\u0131s\u0131 veya API'nin durumu gibi d\u0131\u015f etkenlere ba\u011f\u0131ml\u0131 hale geliriz. \u0130\u015fte burada Jest.spyOn devreye girer. <\/p>\n<pre><code>axios<\/pre>\n<p><\/code> gibi bir HTTP istemcisinin <\/p>\n<pre><code>get<\/pre>\n<p><\/code> metodunu casuslayarak, sahte bir API yan\u0131t\u0131 d\u00f6nd\u00fcrebiliriz.<\/p>\n<pre><code>\n\/\/ userService.js\nconst axios = require('axios');\n\nconst UserService = {\n  async getUser(userId) {\n    try {\n      const response = await axios.get(<code>https:\/\/api.example.com\/users\/${userId}<\/code>);\n      return response.data;\n    } catch (error) {\n      console.error('Kullan\u0131c\u0131 bilgileri al\u0131namad\u0131:', error.message);\n      throw new Error('Kullan\u0131c\u0131 bilgileri al\u0131namad\u0131.');\n    }\n  },\n\n  async createUser(userData) {\n    try {\n      const response = await axios.post('https:\/\/api.example.com\/users', userData);\n      return response.data;\n    } catch (error) {\n      console.error('Kullan\u0131c\u0131 olu\u015fturulamad\u0131:', error.message);\n      throw new Error('Kullan\u0131c\u0131 olu\u015fturulamad\u0131.');\n    }\n  }\n};\n\nmodule.exports = UserService;\n  <\/pre>\n<p><\/code><\/p>\n<p>\u015eimdi bu servisi test edelim. Axios'un get metodunu casuslayarak sahte bir yan\u0131t d\u00f6nd\u00fcrece\u011fiz:<\/p>\n<pre><code>\n\/\/ userService.test.js\nconst UserService = require('.\/userService');\nconst axios = require('axios');\n\ndescribe('UserService', () => {\n  let axiosGetSpy;\n  let axiosPostSpy;\n\n  beforeEach(() => {\n    \/\/ axios.get metodunu casusla\n    axiosGetSpy = jest.spyOn(axios, 'get');\n    axiosPostSpy = jest.spyOn(axios, 'post');\n  });\n\n  afterEach(() => {\n    axiosGetSpy.mockRestore(); \/\/ Casusu temizle\n    axiosPostSpy.mockRestore(); \/\/ Casusu temizle\n  });\n\n  test('getUser, ba\u015far\u0131l\u0131 bir API yan\u0131t\u0131 d\u00f6nd\u00fcrmeli', async () => {\n    const mockUserData = { id: 1, name: 'Alice', email: 'alice@example.com' };\n    axiosGetSpy.mockResolvedValue({ data: mockUserData }); \/\/ Sahte yan\u0131t ayarla\n\n    const user = await UserService.getUser(1);\n\n    expect(axiosGetSpy).toHaveBeenCalledTimes(1);\n    expect(axiosGetSpy).toHaveBeenCalledWith('https:\/\/api.example.com\/users\/1');\n    expect(user).toEqual(mockUserData);\n  });\n\n  test('getUser, API hatas\u0131 durumunda bir hata f\u0131rlatmal\u0131', async () => {\n    const errorMessage = 'Network Error';\n    axiosGetSpy.mockRejectedValue(new Error(errorMessage)); \/\/ Sahte hata ayarla\n\n    await expect(UserService.getUser(1)).rejects.toThrow('Kullan\u0131c\u0131 bilgileri al\u0131namad\u0131.');\n    expect(axiosGetSpy).toHaveBeenCalledTimes(1);\n    expect(axiosGetSpy).toHaveBeenCalledWith('https:\/\/api.example.com\/users\/1');\n  });\n\n  test('createUser, ba\u015far\u0131l\u0131 bir kullan\u0131c\u0131 olu\u015fturma yan\u0131t\u0131 d\u00f6nd\u00fcrmeli', async () => {\n    const newUser = { name: 'Bob', email: 'bob@example.com' };\n    const createdUser = { id: 2, ...newUser };\n    axiosPostSpy.mockResolvedValue({ data: createdUser });\n\n    const result = await UserService.createUser(newUser);\n\n    expect(axiosPostSpy).toHaveBeenCalledTimes(1);\n    expect(axiosPostSpy).toHaveBeenCalledWith('https:\/\/api.example.com\/users', newUser);\n    expect(result).toEqual(createdUser);\n  });\n});\n  <\/pre>\n<p><\/code><\/p>\n<p>Bu testlerde, <code>axios.get<\/code> ve <code>axios.post<\/code> metotlar\u0131n\u0131 casuslayarak, ger\u00e7ek API \u00e7a\u011fr\u0131lar\u0131n\u0131 engelledik. Bunun yerine, <code>.mockResolvedValue()<\/code> veya <code>.mockRejectedValue()<\/code> kullanarak, sanki API'den yan\u0131t geliyormu\u015f gibi sahte senaryolar olu\u015fturduk. Bu sayede, <code>UserService<\/code>'in API \u00e7a\u011fr\u0131s\u0131n\u0131n ba\u015far\u0131l\u0131 veya ba\u015far\u0131s\u0131z oldu\u011fu durumlarda do\u011fru davran\u0131p davranmad\u0131\u011f\u0131n\u0131 h\u0131zl\u0131 ve g\u00fcvenilir bir \u015fekilde test edebiliriz.<\/p>\n<h3>Senaryo 2: Veritaban\u0131 Operasyonunu Casuslama<\/h3>\n<p>Veritaban\u0131 etkile\u015fimleri, birim testlerinde s\u0131k\u00e7a kar\u015f\u0131la\u015f\u0131lan bir ba\u015fka ba\u011f\u0131ml\u0131l\u0131kt\u0131r. Bir modelin veritaban\u0131na veri kaydetme veya sorgulama metodunu test ederken, ger\u00e7ek veritaban\u0131 ba\u011flant\u0131s\u0131 kurmak yerine bu operasyonlar\u0131 casuslamak \u00e7ok daha etkilidir. Diyelim ki, bir <\/p>\n<pre><code>Product<\/pre>\n<p><\/code> modelimiz var ve bu modelin <\/p>\n<pre><code>save()<\/pre>\n<p><\/code> metodu, veritaban\u0131na yeni bir \u00fcr\u00fcn kaydeder.<\/p>\n<pre><code>\n\/\/ productModel.js\nconst db = { \/\/ Basit bir veritaban\u0131 sim\u00fclasyonu\n  products: [],\n  save: async (collection, data) => {\n    \/\/ Ger\u00e7ekte burada bir veritaban\u0131 i\u015flemi olur\n    return new Promise(resolve => {\n      const newRecord = { id: db[collection].length + 1, ...data };\n      db[collection].push(newRecord);\n      setTimeout(() => resolve(newRecord), 50); \/\/ Asenkronluk i\u00e7in gecikme\n    });\n  },\n  find: async (collection, query) => {\n    return new Promise(resolve => {\n      const result = db[collection].filter(item => Object.keys(query).every(key => item[key] === query[key]));\n      setTimeout(() => resolve(result), 50);\n    });\n  }\n};\n\nclass Product {\n  constructor(name, price) {\n    this.name = name;\n    this.price = price;\n  }\n\n  async save() {\n    console.log(<code>\u00dcr\u00fcn ${this.name} kaydediliyor...<\/code>);\n    const savedProduct = await db.save('products', { name: this.name, price: this.price });\n    console.log(<code>\u00dcr\u00fcn kaydedildi: ${savedProduct.id}<\/code>);\n    return savedProduct;\n  }\n\n  static async findByName(name) {\n    console.log(<code>\u00dcr\u00fcn aran\u0131yor: ${name}<\/code>);\n    const products = await db.find('products', { name });\n    return products;\n  }\n}\n\nmodule.exports = Product;\n  <\/pre>\n<p><\/code><\/p>\n<p>Bu <code>Product<\/code> modelini test ederken, <code>db.save<\/code> ve <code>db.find<\/code> metotlar\u0131n\u0131 casuslayarak veritaban\u0131 etkile\u015fimini kontrol edebiliriz:<\/p>\n<pre><code>\n\/\/ productModel.test.js\nconst Product = require('.\/productModel');\nconst db = require('.\/productModel').db; \/\/ db objesini de import ediyoruz\n\ndescribe('Product Model', () => {\n  let dbSaveSpy;\n  let dbFindSpy;\n\n  beforeEach(() => {\n    dbSaveSpy = jest.spyOn(db, 'save');\n    dbFindSpy = jest.spyOn(db, 'find');\n  });\n\n  afterEach(() => {\n    dbSaveSpy.mockRestore();\n    dbFindSpy.mockRestore();\n  });\n\n  test('save metodu db.save metodunu do\u011fru arg\u00fcmanlarla \u00e7a\u011f\u0131rmal\u0131 ve \u00fcr\u00fcn\u00fc kaydetmeli', async () => {\n    const mockSavedProduct = { id: 101, name: 'Test Product', price: 99.99 };\n    dbSaveSpy.mockResolvedValue(mockSavedProduct); \/\/ Sahte DB yan\u0131t\u0131\n\n    const product = new Product('Test Product', 99.99);\n    const saved = await product.save();\n\n    expect(dbSaveSpy).toHaveBeenCalledTimes(1);\n    expect(dbSaveSpy).toHaveBeenCalledWith('products', { name: 'Test Product', price: 99.99 });\n    expect(saved).toEqual(mockSavedProduct);\n  });\n\n  test('findByName metodu db.find metodunu do\u011fru arg\u00fcmanlarla \u00e7a\u011f\u0131rmal\u0131 ve \u00fcr\u00fcnleri d\u00f6nd\u00fcrmeli', async () => {\n    const mockProducts = [{ id: 201, name: 'Laptop', price: 1200 }];\n    dbFindSpy.mockResolvedValue(mockProducts);\n\n    const foundProducts = await Product.findByName('Laptop');\n\n    expect(dbFindSpy).toHaveBeenCalledTimes(1);\n    expect(dbFindSpy).toHaveBeenCalledWith('products', { name: 'Laptop' });\n    expect(foundProducts).toEqual(mockProducts);\n  });\n\n  test('save metodu bir hata durumunda hatay\u0131 yukar\u0131 f\u0131rlatmal\u0131', async () => {\n    const errorMessage = 'Veritaban\u0131 ba\u011flant\u0131 hatas\u0131!';\n    dbSaveSpy.mockRejectedValue(new Error(errorMessage));\n\n    const product = new Product('Hatal\u0131 \u00dcr\u00fcn', 10.00);\n    await expect(product.save()).rejects.toThrow(errorMessage);\n    expect(dbSaveSpy).toHaveBeenCalledTimes(1);\n  });\n});\n  <\/pre>\n<p><\/code><\/p>\n<p>Bu senaryolarda g\u00f6r\u00fcld\u00fc\u011f\u00fc gibi, Jest.spyOn ile d\u0131\u015f ba\u011f\u0131ml\u0131l\u0131klar\u0131 kontrol alt\u0131na alarak sadece odakland\u0131\u011f\u0131n\u0131z birimin mant\u0131\u011f\u0131n\u0131 test edebilirsiniz. Bu, testlerinizi daha h\u0131zl\u0131, daha g\u00fcvenilir ve daha anlaml\u0131 hale getirir. \u00d6zellikle asenkron operasyonlarda <\/p>\n<pre><code>.mockResolvedValue()<\/pre>\n<p><\/code> ve <\/p>\n<pre><code>.mockRejectedValue()<\/pre>\n<p><\/code> kullan\u0131m\u0131, ba\u015far\u0131 ve hata senaryolar\u0131n\u0131 kolayca taklit etmenizi sa\u011flayarak test kapsam\u0131n\u0131z\u0131 art\u0131r\u0131r.<\/p>\n<h3>Asenkron \u0130\u015flemler ve Promise'lerle \u00c7al\u0131\u015fma<\/h3>\n<p>JavaScript ekosisteminde asenkron i\u015flemler, \u00f6zellikle Promise'ler ve async\/await s\u00f6zdizimi, modern uygulamalar\u0131n vazge\u00e7ilmez bir par\u00e7as\u0131d\u0131r. Bu asenkron yap\u0131lar\u0131 test ederken, Jest.spyOn'\u0131n sundu\u011fu <\/p>\n<pre><code>.mockResolvedValue()<\/pre>\n<p><\/code> ve <\/p>\n<pre><code>.mockRejectedValue()<\/pre>\n<p><\/code> metotlar\u0131 hayati \u00f6neme sahiptir. Bu metotlar, casuslad\u0131\u011f\u0131n\u0131z asenkron bir metodun bir Promise'i ba\u015far\u0131yla \u00e7\u00f6z\u00fcmlemesini veya bir hata ile reddetmesini taklit etmenizi sa\u011flar.<\/p>\n<p>\u00d6rne\u011fin, bir e-posta g\u00f6nderme servisimiz olsun:<\/p>\n<pre><code>\n\/\/ emailService.js\nconst Mailer = { \/\/ Harici bir mailer k\u00fct\u00fcphanesini sim\u00fcle ediyoruz\n  send: async (to, subject, body) => {\n    return new Promise((resolve, reject) => {\n      \/\/ Ger\u00e7ekte burada bir API \u00e7a\u011fr\u0131s\u0131 veya SMTP ba\u011flant\u0131s\u0131 olur\n      console.log(<code>E-posta g\u00f6nderiliyor: ${subject} -> ${to}<\/code>);\n      if (to && subject && body) {\n        setTimeout(() => resolve({ success: true, message: 'E-posta ba\u015far\u0131yla g\u00f6nderildi.' }), 100);\n      } else {\n        setTimeout(() => reject(new Error('E-posta g\u00f6nderme ba\u015far\u0131s\u0131z: Eksik bilgi.')), 100);\n      }\n    });\n  }\n};\n\nclass EmailService {\n  async sendWelcomeEmail(userEmail) {\n    if (!userEmail) {\n      throw new Error('Kullan\u0131c\u0131 e-posta adresi bo\u015f olamaz.');\n    }\n    const subject = 'Ho\u015f Geldiniz!';\n    const body = 'Uygulamam\u0131za ho\u015f geldiniz!';\n    return await Mailer.send(userEmail, subject, body);\n  }\n\n  async sendPasswordResetEmail(userEmail, token) {\n    if (!userEmail || !token) {\n      throw new Error('E-posta veya token bo\u015f olamaz.');\n    }\n    const subject = '\u015eifre S\u0131f\u0131rlama';\n    const body = <code>\u015eifrenizi s\u0131f\u0131rlamak i\u00e7in \u015fu linki kullan\u0131n: \/reset?token=${token}<\/code>;\n    return await Mailer.send(userEmail, subject, body);\n  }\n}\n\nmodule.exports = new EmailService(); \/\/ Tekil bir \u00f6rnek d\u0131\u015fa aktar\u0131l\u0131yor\n  <\/pre>\n<p><\/code><\/p>\n<p>\u015eimdi bu <code>EmailService<\/code>'i test edelim:<\/p>\n<pre><code>\n\/\/ emailService.test.js\nconst EmailService = require('.\/emailService');\nconst Mailer = require('.\/emailService').Mailer; \/\/ Mailer objesini de import ediyoruz\n\ndescribe('EmailService', () => {\n  let mailerSendSpy;\n\n  beforeEach(() => {\n    mailerSendSpy = jest.spyOn(Mailer, 'send');\n  });\n\n  afterEach(() => {\n    mailerSendSpy.mockRestore();\n  });\n\n  test('sendWelcomeEmail ba\u015far\u0131l\u0131 oldu\u011funda do\u011fru mesaj\u0131 d\u00f6nd\u00fcrmeli', async () => {\n    const successResponse = { success: true, message: 'E-posta ba\u015far\u0131yla g\u00f6nderildi.' };\n    mailerSendSpy.mockResolvedValue(successResponse);\n\n    const result = await EmailService.sendWelcomeEmail('test@example.com');\n\n    expect(mailerSendSpy).toHaveBeenCalledTimes(1);\n    expect(mailerSendSpy).toHaveBeenCalledWith('test@example.com', 'Ho\u015f Geldiniz!', 'Uygulamam\u0131za ho\u015f geldiniz!');\n    expect(result).toEqual(successResponse);\n  });\n\n  test('sendWelcomeEmail e-posta adresi bo\u015fsa hata f\u0131rlatmal\u0131', async () => {\n    \/\/ Bu durumda Mailer.send \u00e7a\u011fr\u0131lmayacak, sadece EmailService'in kendi kontrol\u00fc test ediliyor\n    await expect(EmailService.sendWelcomeEmail(null)).rejects.toThrow('Kullan\u0131c\u0131 e-posta adresi bo\u015f olamaz.');\n    expect(mailerSendSpy).not.toHaveBeenCalled(); \/\/ Mailer.send metodu \u00e7a\u011fr\u0131lmamal\u0131\n  });\n\n  test('sendPasswordResetEmail g\u00f6nderim hatas\u0131 durumunda bir hata f\u0131rlatmal\u0131', async () => {\n    const error = new Error('Mail sunucusuna ba\u011flan\u0131lamad\u0131.');\n    mailerSendSpy.mockRejectedValue(error); \/\/ Hata durumunu sim\u00fcle et\n\n    await expect(EmailService.sendPasswordResetEmail('test@example.com', 'some-token-123')).rejects.toThrow(error);\n    expect(mailerSendSpy).toHaveBeenCalledTimes(1);\n    expect(mailerSendSpy).toHaveBeenCalledWith('test@example.com', '\u015eifre S\u0131f\u0131rlama', expect.stringContaining('\/reset?token=some-token-123'));\n  });\n});\n  <\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, <code>Mailer.send<\/code> metodu Promise d\u00f6nd\u00fcrd\u00fc\u011f\u00fc i\u00e7in, Jest.spyOn ile <code>.mockResolvedValue()<\/code> ve <code>.mockRejectedValue()<\/code> kullanarak asenkron ba\u015far\u0131 ve hata senaryolar\u0131n\u0131 test ettik. Bu, testlerin ger\u00e7ek bir e-posta sunucusuna ba\u011flanmas\u0131n\u0131 engeller ve testlerinizi \u00e7ok daha h\u0131zl\u0131 ve g\u00fcvenilir hale getirir. Asenkron testlerde <code>await<\/code> anahtar kelimesini ve <code>.rejects.toThrow()<\/code> gibi Jest e\u015fle\u015ftiricilerini do\u011fru kullanmak da \u00f6nemlidir.<\/p>\n<h2>Jest.spyOn \u0130leri D\u00fczey Kullan\u0131m Teknikleri ve En \u0130yi Pratikler<\/h2>\n<p>Jest.spyOn'\u0131n temel kullan\u0131m\u0131 olduk\u00e7a anla\u015f\u0131l\u0131r olsa da, bu arac\u0131 daha etkili ve verimli bir \u015fekilde kullanmak i\u00e7in baz\u0131 ileri d\u00fczey teknikler ve en iyi pratikler mevcuttur. \u00d6zellikle karma\u015f\u0131k test senaryolar\u0131nda, bu teknikler testlerinizin okunabilirli\u011fini, bak\u0131m\u0131n\u0131 ve g\u00fcvenilirli\u011fini art\u0131rabilir.<\/p>\n<h3>Jest.spyOn vs. jest.fn() vs. jest.mock(): Ne Zaman Hangisini Kullanmal\u0131?<\/h3>\n<p>Jest'in mocking ekosisteminde \u00fc\u00e7 ana ara\u00e7 vard\u0131r: <code>jest.spyOn()<\/code>, <code>jest.fn()<\/code> ve <code>jest.mock()<\/code>. Her birinin kendine \u00f6zg\u00fc kullan\u0131m durumlar\u0131 vard\u0131r ve do\u011fru arac\u0131 se\u00e7mek, testlerinizin kalitesi i\u00e7in kritiktir.<\/p>\n<ul>\n<li>\n<pre><code>jest.fn()<\/pre>\n<p><\/code>: S\u0131f\u0131rdan tamamen yeni bir sahte fonksiyon olu\u015fturur. Genellikle bir callback'i test etmek, bir objeye yeni bir metot eklemek veya bir fonksiyonu parametre olarak ge\u00e7irmek istedi\u011finizde kullan\u0131l\u0131r. Orijinal bir implementasyonu yoktur.<\/p>\n<pre><code>\n        const mockCallback = jest.fn();\n        someFunction(mockCallback);\n        expect(mockCallback).toHaveBeenCalled();\n      <\/pre>\n<p><\/code>\n    <\/li>\n<li>\n<pre><code>jest.spyOn(object, methodName)<\/pre>\n<p><\/code>: Var olan bir objenin bir metodunu casuslar. Metodun orijinal implementasyonunu varsay\u0131lan olarak korur, ancak \u00e7a\u011fr\u0131lar\u0131 izlemenize ve metodun davran\u0131\u015f\u0131n\u0131 ge\u00e7ici olarak de\u011fi\u015ftirmenize olanak tan\u0131r. Genellikle, bir mod\u00fcl i\u00e7indeki ba\u015fka bir metodun veya bir d\u0131\u015f ba\u011f\u0131ml\u0131l\u0131\u011f\u0131n (\u00f6rne\u011fin <\/p>\n<pre><code>console.log<\/pre>\n<p><\/code>, <\/p>\n<pre><code>axios.get<\/pre>\n<p><\/code>) bir metodunun \u00e7a\u011fr\u0131ld\u0131\u011f\u0131ndan emin olmak istedi\u011finizde veya o metodun d\u00f6n\u00fc\u015f de\u011ferini kontrol etmek istedi\u011finizde tercih edilir. Casuslanan metodun orijinal haline geri d\u00f6nd\u00fcr\u00fclmesi (<code>.mockRestore()<\/code>) \u00f6nemlidir.<\/p>\n<pre><code>\n        const consoleSpy = jest.spyOn(console, 'log');\n        myFunction(); \/\/ myFunction i\u00e7inde console.log \u00e7a\u011fr\u0131l\u0131yor\n        expect(consoleSpy).toHaveBeenCalledWith('Bir \u015feyler oldu.');\n        consoleSpy.mockRestore();\n      <\/pre>\n<p><\/code>\n    <\/li>\n<li>\n<pre><code>jest.mock('modulePath')<\/pre>\n<p><\/code>: T\u00fcm bir mod\u00fcl\u00fc sahtelemenizi sa\u011flar. Genellikle, test etti\u011finiz mod\u00fcl\u00fcn b\u00fcy\u00fck ve karma\u015f\u0131k bir ba\u011f\u0131ml\u0131l\u0131\u011f\u0131 (\u00f6rne\u011fin bir veritaban\u0131 k\u00fct\u00fcphanesi veya \u00fc\u00e7\u00fcnc\u00fc taraf bir API istemcisi) oldu\u011funda kullan\u0131l\u0131r. Bu, mod\u00fcl\u00fcn t\u00fcm d\u0131\u015fa aktar\u0131mlar\u0131n\u0131 (export) sahte versiyonlarla de\u011fi\u015ftirir.<\/p>\n<pre><code>\n        \/\/ __mocks__\/lodash.js (veya test dosyas\u0131nda)\n        jest.mock('lodash', () => ({\n          ...jest.requireActual('lodash'), \/\/ Ger\u00e7ek implementasyondan baz\u0131lar\u0131n\u0131 koru\n          chunk: jest.fn(() => ['mockedChunk'])\n        }));\n\n        const _ = require('lodash');\n        _.chunk([1,2,3], 2);\n        expect(_.chunk).toHaveBeenCalled();\n      <\/pre>\n<p><\/code>\n    <\/li>\n<\/ul>\n<p>\u00d6zetle: Bir fonksiyonu tamamen sahtelemeniz gerekiyorsa <\/p>\n<pre><code>jest.fn()<\/pre>\n<p><\/code> kullan\u0131n. Bir objenin mevcut bir metodunu izlemek ve\/veya ge\u00e7ici olarak de\u011fi\u015ftirmek istiyorsan\u0131z <\/p>\n<pre><code>jest.spyOn()<\/pre>\n<p><\/code> kullan\u0131n. T\u00fcm bir mod\u00fcl\u00fcn ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 izole etmek istiyorsan\u0131z <\/p>\n<pre><code>jest.mock()<\/pre>\n<p><\/code> kullan\u0131n.<\/p>\n<h3>Zincirleme Spy'lar ve Karma\u015f\u0131k Senaryolar<\/h3>\n<p>Bazen bir metot, di\u011fer metotlar\u0131 \u00e7a\u011f\u0131rabilir veya birden fazla ard\u0131\u015f\u0131k i\u015flemi tetikleyebilir. Jest.spyOn'\u0131 zincirleme kullanarak bu karma\u015f\u0131k ak\u0131\u015flar\u0131 test edebilirsiniz. \u00d6rne\u011fin, bir metodun \u00f6nce bir do\u011frulama metodunu, sonra bir kaydetme metodunu \u00e7a\u011f\u0131rd\u0131\u011f\u0131ndan emin olmak isteyebilirsiniz. Bu t\u00fcr senaryolarda, birden fazla casus olu\u015fturabilir ve \u00e7a\u011fr\u0131 s\u0131ras\u0131n\u0131 kontrol edebilirsiniz.<\/p>\n<pre><code>\n\/\/ dataProcessor.js\nconst validator = {\n  isValid: (data) => data && data.value > 0\n};\n\nconst dataStore = {\n  save: async (data) => {\n    if (!data.id) data.id = Math.random().toString(36).substr(2, 9);\n    console.log(<code>Veri kaydedildi: ${data.id}<\/code>);\n    return Promise.resolve(data);\n  }\n};\n\nclass DataProcessor {\n  async process(data) {\n    if (!validator.isValid(data)) {\n      throw new Error('Ge\u00e7ersiz veri.');\n    }\n    const result = await dataStore.save(data);\n    return result;\n  }\n}\n\nmodule.exports = new DataProcessor();\n  <\/pre>\n<p><\/code><\/p>\n<p>Test dosyas\u0131nda zincirleme spy'lar:<\/p>\n<pre><code>\n\/\/ dataProcessor.test.js\nconst DataProcessor = require('.\/dataProcessor');\nconst validator = require('.\/dataProcessor').validator;\nconst dataStore = require('.\/dataProcessor').dataStore;\n\ndescribe('DataProcessor', () => {\n  let isValidSpy;\n  let saveSpy;\n\n  beforeEach(() => {\n    isValidSpy = jest.spyOn(validator, 'isValid');\n    saveSpy = jest.spyOn(dataStore, 'save');\n  });\n\n  afterEach(() => {\n    isValidSpy.mockRestore();\n    saveSpy.mockRestore();\n  });\n\n  test('process metodu ge\u00e7erli veriyi ba\u015far\u0131yla i\u015flemeli', async () => {\n    const testData = { value: 10 };\n    const savedData = { id: 'abc', value: 10 };\n\n    isValidSpy.mockReturnValue(true); \/\/ Do\u011frulaman\u0131n ba\u015far\u0131l\u0131 oldu\u011funu varsay\n    saveSpy.mockResolvedValue(savedData); \/\/ Kaydetmenin ba\u015far\u0131l\u0131 oldu\u011funu varsay\n\n    const result = await DataProcessor.process(testData);\n\n    expect(isValidSpy).toHaveBeenCalledTimes(1);\n    expect(isValidSpy).toHaveBeenCalledWith(testData);\n    expect(saveSpy).toHaveBeenCalledTimes(1);\n    expect(saveSpy).toHaveBeenCalledWith(testData);\n    expect(result).toEqual(savedData);\n\n    \/\/ Call order (\u00e7a\u011fr\u0131 s\u0131ras\u0131) da Jest'te kontrol edilebilir,\n    \/\/ ancak bunun i\u00e7in daha \u00f6zel bir yakla\u015f\u0131m gerekebilir veya\n    \/\/ metotlar\u0131n \u00e7a\u011fr\u0131lma s\u0131ras\u0131n\u0131 dolayl\u0131 yollardan test edilebilir.\n    \/\/ \u00d6rne\u011fin, mock fonksiyonlar\u0131n\u0131n \u00e7a\u011fr\u0131lma s\u0131ras\u0131n\u0131 dizi olarak tutarak kar\u015f\u0131la\u015ft\u0131rabilirsiniz.\n  });\n\n  test('process metodu ge\u00e7ersiz veri i\u00e7in hata f\u0131rlatmal\u0131', async () => {\n    const invalidData = { value: -5 };\n    isValidSpy.mockReturnValue(false); \/\/ Do\u011frulaman\u0131n ba\u015far\u0131s\u0131z oldu\u011funu varsay\n\n    await expect(DataProcessor.process(invalidData)).rejects.toThrow('Ge\u00e7ersiz veri.');\n\n    expect(isValidSpy).toHaveBeenCalledTimes(1);\n    expect(isValidSpy).toHaveBeenCalledWith(invalidData);\n    expect(saveSpy).not.toHaveBeenCalled(); \/\/ Ge\u00e7ersiz veri oldu\u011funda save metodu \u00e7a\u011fr\u0131lmamal\u0131\n  });\n});\n  <\/pre>\n<p><\/code><\/p>\n<p>Bu senaryoda, <code>DataProcessor<\/code>'\u0131n i\u00e7 ba\u011f\u0131ml\u0131l\u0131klar\u0131 olan <\/p>\n<pre><code>validator.isValid<\/pre>\n<p><\/code> ve <\/p>\n<pre><code>dataStore.save<\/pre>\n<p><\/code> metotlar\u0131n\u0131 casuslad\u0131k. Bu, <code>DataProcessor.process<\/code> metodunun hem ge\u00e7erli hem de ge\u00e7ersiz veri ak\u0131\u015flar\u0131n\u0131 izole bir \u015fekilde test etmemizi sa\u011flad\u0131. \u00d6zellikle <\/p>\n<pre><code>saveSpy.not.toHaveBeenCalled()<\/pre>\n<p><\/code> gibi asercyonlar, negatif test senaryolar\u0131nda beklenen yan etkilerin ger\u00e7ekten olu\u015fmad\u0131\u011f\u0131n\u0131 do\u011frulamak i\u00e7in \u00e7ok de\u011ferlidir.<\/p>\n<h3>Haf\u0131za Y\u00f6netimi ve Temizleme: mockRestore, clearAllMocks, resetAllMocks<\/h3>\n<p>Testler aras\u0131nda \"s\u0131z\u0131nt\u0131\" olmamas\u0131 i\u00e7in spy'lar\u0131n\u0131z\u0131 her testten sonra temizlemek hayati \u00f6nem ta\u015f\u0131r. Jest, bu konuda size yard\u0131mc\u0131 olacak birka\u00e7 metot sunar:<\/p>\n<ul>\n<li>\n<pre><code>spy.mockRestore()<\/pre>\n<p><\/code>: Belirli bir casuslanan metodun orijinal implementasyonuna geri d\u00f6nmesini sa\u011flar. Bu, en hedefli temizleme y\u00f6ntemidir. Genellikle <\/p>\n<pre><code>afterEach<\/pre>\n<p><\/code> i\u00e7inde tek tek spy'lar i\u00e7in kullan\u0131l\u0131r.\n    <\/li>\n<li>\n<pre><code>jest.clearAllMocks()<\/pre>\n<p><\/code>: T\u00fcm mock fonksiyonlar\u0131n\u0131n (hem <\/p>\n<pre><code>jest.fn()<\/pre>\n<p><\/code> hem de <\/p>\n<pre><code>jest.spyOn()<\/pre>\n<p><\/code> taraf\u0131ndan olu\u015fturulanlar) \u00e7a\u011fr\u0131 ge\u00e7mi\u015flerini (<code>.mock.calls<\/code>, <code>.mock.results<\/code> vb.) s\u0131f\u0131rlar, ancak orijinal implementasyonlar\u0131 geri getirmez veya mock edilmi\u015f de\u011ferleri kald\u0131rmaz. Fonksiyonlar hala mock edilmi\u015f durumda kal\u0131r.\n    <\/li>\n<li>\n<pre><code>jest.resetAllMocks()<\/pre>\n<p><\/code>: T\u00fcm mock fonksiyonlar\u0131n\u0131n \u00e7a\u011fr\u0131 ge\u00e7mi\u015flerini s\u0131f\u0131rlar VE mock implementasyonlar\u0131n\u0131 da s\u0131f\u0131rlar (yani <\/p>\n<pre><code>.mockReturnValue()<\/pre>\n<p><\/code>, <\/p>\n<pre><code>.mockImplementation()<\/pre>\n<p><\/code> ile belirlenen de\u011ferleri kald\u0131r\u0131r). Ancak <\/p>\n<pre><code>jest.spyOn()<\/pre>\n<p><\/code> ile casuslanan metotlar\u0131n orijinal implementasyonlar\u0131n\u0131 geri getirmez.\n    <\/li>\n<li>\n<pre><code>jest.restoreAllMocks()<\/pre>\n<p><\/code>: T\u00fcm mock fonksiyonlar\u0131n\u0131n \u00e7a\u011fr\u0131 ge\u00e7mi\u015flerini s\u0131f\u0131rlar, mock implementasyonlar\u0131n\u0131 kald\u0131r\u0131r VE <\/p>\n<pre><code>jest.spyOn()<\/pre>\n<p><\/code> ile casuslanan t\u00fcm metotlar\u0131 orijinal implementasyonlar\u0131na geri d\u00f6nd\u00fcr\u00fcr. Bu, genellikle test s\u00fcitinizin ba\u015f\u0131nda veya sonunda, t\u00fcm mock'lar\u0131 tam olarak temizlemek i\u00e7in en kapsaml\u0131 ve g\u00fcvenli se\u00e7enektir.\n    <\/li>\n<\/ul>\n<p>En iyi pratik olarak, her test blo\u011fu i\u00e7inde <\/p>\n<pre><code>jest.spyOn()<\/pre>\n<p><\/code> ile olu\u015fturdu\u011funuz spy'lar\u0131 <\/p>\n<pre><code>afterEach(() => spy.mockRestore())<\/pre>\n<p><\/code> ile geri y\u00fcklemeniz \u00f6nerilir. E\u011fer \u00e7ok say\u0131da spy veya mock fonksiyonunuz varsa, <\/p>\n<pre><code>jest.restoreAllMocks()<\/pre>\n<p><\/code> metodunu <\/p>\n<pre><code>afterEach<\/pre>\n<p><\/code> blo\u011funda kullanmak, t\u00fcm casuslar\u0131 otomatik olarak orijinal hallerine d\u00f6nd\u00fcrmek i\u00e7in pratik bir yoldur. Bu, testlerinizin ba\u011f\u0131ms\u0131zl\u0131\u011f\u0131n\u0131 garanti eder ve olas\u0131 yan etkileri ortadan kald\u0131r\u0131r.<\/p>\n<h2>Sonu\u00e7: Jest.spyOn ile Testlerinizi G\u00fc\u00e7lendirin<\/h2>\n<p>Bu kapsaml\u0131 rehber boyunca, Jest.spyOn'\u0131n birim test stratejiniz i\u00e7in neden bu kadar \u00f6nemli bir ara\u00e7 oldu\u011funu, temelden ileri d\u00fczeye kadar nas\u0131l kullan\u0131ld\u0131\u011f\u0131n\u0131 ve ger\u00e7ek d\u00fcnya senaryolar\u0131nda kar\u015f\u0131la\u015f\u0131lan karma\u015f\u0131k ba\u011f\u0131ml\u0131l\u0131klar\u0131n \u00fcstesinden nas\u0131l gelindi\u011fini detayl\u0131 bir \u015fekilde inceledik. Jest.spyOn, kodunuzdaki belirli metotlar\u0131n davran\u0131\u015flar\u0131n\u0131 izlemenize, bu metotlar\u0131n \u00e7a\u011fr\u0131 ge\u00e7mi\u015flerini kaydetmenize ve hatta ge\u00e7ici olarak d\u00f6n\u00fc\u015f de\u011ferlerini veya implementasyonlar\u0131n\u0131 de\u011fi\u015ftirmenize olanak tan\u0131r. Bu yetenek, \u00f6zellikle d\u0131\u015f ba\u011f\u0131ml\u0131l\u0131klar\u0131 (API \u00e7a\u011fr\u0131lar\u0131, veritaban\u0131 etkile\u015fimleri, dosya sistemi i\u015flemleri vb.) olan fonksiyonlar\u0131 test ederken hayati bir rol oynar. Testlerinizin daha h\u0131zl\u0131, daha g\u00fcvenilir ve daha izole olmas\u0131n\u0131 sa\u011flayarak, geli\u015ftirme s\u00fcre\u00e7lerinizin verimlili\u011fini art\u0131r\u0131r.<\/p>\n<p>\u00d6zellikle, asenkron i\u015flemlerle \u00e7al\u0131\u015f\u0131rken <\/p>\n<pre><code>.mockResolvedValue()<\/pre>\n<p><\/code> ve <\/p>\n<pre><code>.mockRejectedValue()<\/pre>\n<p><\/code> gibi yard\u0131mc\u0131 metotlar\u0131n sa\u011flad\u0131\u011f\u0131 esneklik, ba\u015far\u0131 ve hata senaryolar\u0131n\u0131 kolayca sim\u00fcle etmenizi m\u00fcmk\u00fcn k\u0131lar. Bu sayede, uygulaman\u0131z\u0131n farkl\u0131 ko\u015fullar alt\u0131nda nas\u0131l davrand\u0131\u011f\u0131n\u0131 g\u00fcvenle test edebilirsiniz. Ayr\u0131ca, <\/p>\n<pre><code>jest.spyOn()<\/pre>\n<p><\/code>, <\/p>\n<pre><code>jest.fn()<\/pre>\n<p><\/code> ve <\/p>\n<pre><code>jest.mock()<\/pre>\n<p><\/code> aras\u0131ndaki farklar\u0131 anlamak, her senaryo i\u00e7in do\u011fru arac\u0131 se\u00e7menize yard\u0131mc\u0131 olur ve test kodunuzun daha temiz ve s\u00fcrd\u00fcr\u00fclebilir olmas\u0131n\u0131 sa\u011flar. Testler aras\u0131nda istenmeyen yan etkileri \u00f6nlemek i\u00e7in <\/p>\n<pre><code>.mockRestore()<\/pre>\n<p><\/code> veya <\/p>\n<pre><code>jest.restoreAllMocks()<\/pre>\n<p><\/code> gibi temizlik metotlar\u0131n\u0131 <\/p>\n<pre><code>afterEach<\/pre>\n<p><\/code> bloklar\u0131nda kullanmak, her zaman iyi bir uygulama olarak kar\u015f\u0131m\u0131za \u00e7\u0131kar.<\/p>\n<p>Sonu\u00e7 olarak, Jest.spyOn, modern JavaScript geli\u015ftiricileri i\u00e7in vazge\u00e7ilmez bir birim testi arac\u0131d\u0131r. Kodunuzun mod\u00fclerli\u011fini art\u0131r\u0131r, hata ay\u0131klama s\u00fcre\u00e7lerini basitle\u015ftirir ve uygulaman\u0131z\u0131n g\u00fcvenilirli\u011fini \u00f6nemli \u00f6l\u00e7\u00fcde y\u00fckseltir. Bu k\u0131lavuzda edindi\u011finiz bilgilerle, Jest.spyOn'\u0131 kendi projelerinizde etkin bir \u015fekilde kullanarak daha sa\u011flam ve bak\u0131m\u0131 kolay bir kod taban\u0131 olu\u015fturmaya ba\u015flayabilirsiniz. Testlerinizi g\u00fc\u00e7lendirin, kod kalitenizi art\u0131r\u0131n ve geli\u015ftirme s\u00fcre\u00e7lerinizde daha fazla g\u00fcvenle ilerleyin. Unutmay\u0131n, iyi yaz\u0131lm\u0131\u015f testler, sadece hatalar\u0131 yakalamakla kalmaz, ayn\u0131 zamanda kodunuzun bir nevi canl\u0131 dok\u00fcmantasyonu olarak da hizmet eder.<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular<\/h3>\n<ul>\n<li>\n<h4>Jest.spyOn nedir ve neden kullanmal\u0131y\u0131m?<\/h4>\n<p>Jest.spyOn, bir objenin mevcut bir metodunu casuslamak (\u00e7a\u011fr\u0131lar\u0131n\u0131 izlemek) ve\/veya ge\u00e7ici olarak davran\u0131\u015f\u0131n\u0131 de\u011fi\u015ftirmek i\u00e7in kullan\u0131lan bir Jest arac\u0131d\u0131r. D\u0131\u015f ba\u011f\u0131ml\u0131l\u0131klar\u0131 olan fonksiyonlar\u0131 izole bir \u015fekilde test etmek, testleri h\u0131zland\u0131rmak ve karars\u0131z testleri \u00f6nlemek i\u00e7in kullanmal\u0131s\u0131n\u0131z. Metodun orijinal implementasyonunu korurken, \u00e7a\u011fr\u0131 ge\u00e7mi\u015fini (hangi arg\u00fcmanlarla \u00e7a\u011fr\u0131ld\u0131, ka\u00e7 kez \u00e7a\u011fr\u0131ld\u0131 vb.) kaydetmenize olanak tan\u0131r.<\/p>\n<\/li>\n<li>\n<h4>Jest.spyOn ile jest.fn() aras\u0131ndaki temel fark nedir?<\/h4>\n<p>Jest.fn() s\u0131f\u0131rdan tamamen yeni bir sahte (mock) fonksiyon olu\u015ftururken, jest.spyOn var olan bir objenin mevcut bir metodunu casuslar. jest.spyOn ile casuslad\u0131\u011f\u0131n\u0131z metodun orijinal implementasyonu varsay\u0131lan olarak \u00e7al\u0131\u015fmaya devam ederken, jest.fn() bir \"bo\u015f\" fonksiyonla ba\u015flar ve ona \u00f6zel bir implementasyon ataman\u0131z gerekir. spyOn, \u00f6zellikle bir objenin i\u00e7indeki bir metodun \u00e7a\u011fr\u0131l\u0131p \u00e7a\u011fr\u0131lmad\u0131\u011f\u0131n\u0131 kontrol etmek veya davran\u0131\u015f\u0131n\u0131 ge\u00e7ici olarak taklit etmek istedi\u011finizde daha uygundur.<\/p>\n<\/li>\n<li>\n<h4>jest.spyOn ile mockResolvedValue ve mockRejectedValue ne zaman kullan\u0131l\u0131r?<\/h4>\n<p>Bu metotlar, asenkron metotlar (Promise d\u00f6nd\u00fcren fonksiyonlar) ile \u00e7al\u0131\u015f\u0131rken kullan\u0131l\u0131r. mockResolvedValue, casuslanan metodun sanki ba\u015far\u0131l\u0131 bir Promise \u00e7\u00f6z\u00fcmlenmi\u015f gibi belirli bir de\u011fer d\u00f6nd\u00fcrmesini sa\u011flar. mockRejectedValue ise, metodun sanki bir Promise hatas\u0131yla reddedilmi\u015f gibi belirli bir hata f\u0131rlatmas\u0131n\u0131 sim\u00fcle eder. \u00d6zellikle API \u00e7a\u011fr\u0131lar\u0131 veya veritaban\u0131 i\u015flemleri gibi asenkron ba\u011f\u0131ml\u0131l\u0131klar\u0131 test ederken vazge\u00e7ilmezdirler.<\/p>\n<\/li>\n<li>\n<h4>Jest.spyOn kullan\u0131rken .mockRestore() neden \u00f6nemlidir?<\/h4>\n<p>.mockRestore() metodu, casuslad\u0131\u011f\u0131n\u0131z metodun orijinal implementasyonuna geri d\u00f6nmesini sa\u011flar. E\u011fer bunu yapmazsan\u0131z, bir testte mocklad\u0131\u011f\u0131n\u0131z bir metot, test s\u00fcitinizdeki di\u011fer testleri de etkileyebilir. Bu durum, \"test s\u0131z\u0131nt\u0131s\u0131\" olarak adland\u0131r\u0131l\u0131r ve testlerin karars\u0131z ve g\u00fcvenilmez olmas\u0131na neden olur. Bu nedenle, her test blo\u011funun sonunda veya afterEach hook'unda .mockRestore() kullanarak casuslar\u0131 temizlemek iyi bir pratik olarak kabul edilir.<\/p>\n<\/li>\n<li>\n<h4>Jest.spyOn ile private metotlar\u0131 test edebilir miyim?<\/h4>\n<p>JavaScript'te ger\u00e7ek \"private\" metot kavram\u0131 do\u011frudan yoktur (class private fields hari\u00e7). Ancak genellikle bir objenin d\u0131\u015fa aktar\u0131lmayan (internal) metotlar\u0131n\u0131 test etme ihtiyac\u0131 do\u011fabilir. Jest.spyOn, sadece objenin eri\u015filebilir (genellikle public) metotlar\u0131 \u00fczerinde \u00e7al\u0131\u015fabilir. E\u011fer bir metot ger\u00e7ekten d\u0131\u015far\u0131dan eri\u015filemezse, do\u011frudan spyOn ile casuslayamazs\u0131n\u0131z. Bu durumda, ya test amac\u0131yla o metodu d\u0131\u015fa aktarmak (ki bu encapsulation prensiplerine ayk\u0131r\u0131 olabilir) ya da o metodu \u00e7a\u011f\u0131ran public metot \u00fczerinden dolayl\u0131 yollarla test etmek daha uygun olabilir. Genellikle, private metotlar\u0131n kendi ba\u015f\u0131na birim testine tabi tutulmas\u0131 yerine, bu metotlar\u0131 kullanan public metotlar\u0131n davran\u0131\u015flar\u0131 \u00fczerinden test edilmesi \u00f6nerilir.<\/p>\n<\/li>\n<\/ul>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Modern JavaScript uygulamalar\u0131nda kod kalitesi ve g\u00fcvenilirli\u011fi, birim testleriyle ba\u015flar. Peki, d\u0131\u015f ba\u011f\u0131ml\u0131l\u0131klar\u0131 olan veya yan etkiler \u00fcreten&hellip;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-31984","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Jest.spyOn: Birim Testleriniz \u0130\u00e7in Kapsaml\u0131 K\u0131lavuz<\/title>\n<meta name=\"description\" content=\"Modern JavaScript uygulamalar\u0131nda kod kalitesi ve g\u00fcvenilirli\u011fi, birim testleriyle ba\u015flar. Peki, d\u0131\u015f ba\u011f\u0131ml\u0131l\u0131klar\u0131 olan veya yan etkiler \u00fcreten fonksiyonlar\u0131 test ederken ne yapmal\u0131s\u0131n\u0131z? Jest.spyOn, bu zorluklar\u0131n \u00fcstesinden gelerek testlerinizi daha izole ve y\u00f6netilebilir hale getirmenizi sa\u011flar. Bu kapsaml\u0131 k\u0131lavuzda, Jest.spyOn&#039;\u0131n ne oldu\u011funu, nas\u0131l kullan\u0131ld\u0131\u011f\u0131n\u0131 ve birim test stratejinizi nas\u0131l d\u00f6n\u00fc\u015ft\u00fcrece\u011fini detaylar\u0131yla \u00f6\u011freneceksiniz.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Jest.spyOn: Birim Testleriniz \u0130\u00e7in Kapsaml\u0131 K\u0131lavuz\" \/>\n<meta property=\"og:description\" content=\"Modern JavaScript uygulamalar\u0131nda kod kalitesi ve g\u00fcvenilirli\u011fi, birim testleriyle ba\u015flar. Peki, d\u0131\u015f ba\u011f\u0131ml\u0131l\u0131klar\u0131 olan veya yan etkiler \u00fcreten fonksiyonlar\u0131 test ederken ne yapmal\u0131s\u0131n\u0131z? Jest.spyOn, bu zorluklar\u0131n \u00fcstesinden gelerek testlerinizi daha izole ve y\u00f6netilebilir hale getirmenizi sa\u011flar. Bu kapsaml\u0131 k\u0131lavuzda, Jest.spyOn&#039;\u0131n ne oldu\u011funu, nas\u0131l kullan\u0131ld\u0131\u011f\u0131n\u0131 ve birim test stratejinizi nas\u0131l d\u00f6n\u00fc\u015ft\u00fcrece\u011fini detaylar\u0131yla \u00f6\u011freneceksiniz.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-16T07:01:25+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"27 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Jest.spyOn: Birim Testleriniz \u0130\u00e7in Kapsaml\u0131 K\u0131lavuz\",\"datePublished\":\"2025-10-16T07:01:25+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/\"},\"wordCount\":3772,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/\",\"name\":\"Jest.spyOn: Birim Testleriniz \u0130\u00e7in Kapsaml\u0131 K\u0131lavuz\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-10-16T07:01:25+00:00\",\"description\":\"Modern JavaScript uygulamalar\u0131nda kod kalitesi ve g\u00fcvenilirli\u011fi, birim testleriyle ba\u015flar. Peki, d\u0131\u015f ba\u011f\u0131ml\u0131l\u0131klar\u0131 olan veya yan etkiler \u00fcreten fonksiyonlar\u0131 test ederken ne yapmal\u0131s\u0131n\u0131z? Jest.spyOn, bu zorluklar\u0131n \u00fcstesinden gelerek testlerinizi daha izole ve y\u00f6netilebilir hale getirmenizi sa\u011flar. Bu kapsaml\u0131 k\u0131lavuzda, Jest.spyOn'\u0131n ne oldu\u011funu, nas\u0131l kullan\u0131ld\u0131\u011f\u0131n\u0131 ve birim test stratejinizi nas\u0131l d\u00f6n\u00fc\u015ft\u00fcrece\u011fini detaylar\u0131yla \u00f6\u011freneceksiniz.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Jest.spyOn: Birim Testleriniz \u0130\u00e7in Kapsaml\u0131 K\u0131lavuz\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Jest.spyOn: Birim Testleriniz \u0130\u00e7in Kapsaml\u0131 K\u0131lavuz","description":"Modern JavaScript uygulamalar\u0131nda kod kalitesi ve g\u00fcvenilirli\u011fi, birim testleriyle ba\u015flar. Peki, d\u0131\u015f ba\u011f\u0131ml\u0131l\u0131klar\u0131 olan veya yan etkiler \u00fcreten fonksiyonlar\u0131 test ederken ne yapmal\u0131s\u0131n\u0131z? Jest.spyOn, bu zorluklar\u0131n \u00fcstesinden gelerek testlerinizi daha izole ve y\u00f6netilebilir hale getirmenizi sa\u011flar. Bu kapsaml\u0131 k\u0131lavuzda, Jest.spyOn'\u0131n ne oldu\u011funu, nas\u0131l kullan\u0131ld\u0131\u011f\u0131n\u0131 ve birim test stratejinizi nas\u0131l d\u00f6n\u00fc\u015ft\u00fcrece\u011fini detaylar\u0131yla \u00f6\u011freneceksiniz.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/","og_locale":"tr_TR","og_type":"article","og_title":"Jest.spyOn: Birim Testleriniz \u0130\u00e7in Kapsaml\u0131 K\u0131lavuz","og_description":"Modern JavaScript uygulamalar\u0131nda kod kalitesi ve g\u00fcvenilirli\u011fi, birim testleriyle ba\u015flar. Peki, d\u0131\u015f ba\u011f\u0131ml\u0131l\u0131klar\u0131 olan veya yan etkiler \u00fcreten fonksiyonlar\u0131 test ederken ne yapmal\u0131s\u0131n\u0131z? Jest.spyOn, bu zorluklar\u0131n \u00fcstesinden gelerek testlerinizi daha izole ve y\u00f6netilebilir hale getirmenizi sa\u011flar. Bu kapsaml\u0131 k\u0131lavuzda, Jest.spyOn'\u0131n ne oldu\u011funu, nas\u0131l kullan\u0131ld\u0131\u011f\u0131n\u0131 ve birim test stratejinizi nas\u0131l d\u00f6n\u00fc\u015ft\u00fcrece\u011fini detaylar\u0131yla \u00f6\u011freneceksiniz.","og_url":"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-10-16T07:01:25+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"27 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Jest.spyOn: Birim Testleriniz \u0130\u00e7in Kapsaml\u0131 K\u0131lavuz","datePublished":"2025-10-16T07:01:25+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/"},"wordCount":3772,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/","url":"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/","name":"Jest.spyOn: Birim Testleriniz \u0130\u00e7in Kapsaml\u0131 K\u0131lavuz","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-10-16T07:01:25+00:00","description":"Modern JavaScript uygulamalar\u0131nda kod kalitesi ve g\u00fcvenilirli\u011fi, birim testleriyle ba\u015flar. Peki, d\u0131\u015f ba\u011f\u0131ml\u0131l\u0131klar\u0131 olan veya yan etkiler \u00fcreten fonksiyonlar\u0131 test ederken ne yapmal\u0131s\u0131n\u0131z? Jest.spyOn, bu zorluklar\u0131n \u00fcstesinden gelerek testlerinizi daha izole ve y\u00f6netilebilir hale getirmenizi sa\u011flar. Bu kapsaml\u0131 k\u0131lavuzda, Jest.spyOn'\u0131n ne oldu\u011funu, nas\u0131l kullan\u0131ld\u0131\u011f\u0131n\u0131 ve birim test stratejinizi nas\u0131l d\u00f6n\u00fc\u015ft\u00fcrece\u011fini detaylar\u0131yla \u00f6\u011freneceksiniz.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/jest-spyon-birim-testleriniz-icin-kapsamli-kilavuz\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Jest.spyOn: Birim Testleriniz \u0130\u00e7in Kapsaml\u0131 K\u0131lavuz"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31984","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=31984"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31984\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=31984"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=31984"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=31984"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}