{"id":36449,"date":"2025-12-17T21:41:01","date_gmt":"2025-12-17T18:41:01","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=36449"},"modified":"2025-12-17T21:41:01","modified_gmt":"2025-12-17T18:41:01","slug":"react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/","title":{"rendered":"React\/Redux Uygulamalar\u0131n\u0131 Jest ve Enzyme ile Test Etmek &#8211; B\u00f6l\u00fcm 4: Redux Reducer&#8217;lar\u0131n\u0131 Test Etmek"},"content":{"rendered":"<p><body><\/p>\n<h2>React\/Redux Uygulamalar\u0131n\u0131 Jest ve Enzyme ile Test Etmek &#8211; B\u00f6l\u00fcm 4: Redux Reducer&#8217;lar\u0131n\u0131 Test Etmek<\/h2>\n<p>Redux, modern React uygulamalar\u0131nda durum y\u00f6netimini (state management) basitle\u015ftiren g\u00fc\u00e7l\u00fc bir k\u00fct\u00fcphanedir. Uygulama durumunun merkezi bir yerde tutulmas\u0131n\u0131 ve \u00f6ng\u00f6r\u00fclebilir bir \u015fekilde de\u011fi\u015ftirilmesini sa\u011flar. Redux ekosisteminin kalbinde ise &#8220;reducer&#8221; ad\u0131 verilen fonksiyonlar bulunur. Bu makale serimizin d\u00f6rd\u00fcnc\u00fc b\u00f6l\u00fcm\u00fcnde, Redux reducer&#8217;lar\u0131n\u0131 Jest ve Enzyme ile nas\u0131l etkin bir \u015fekilde test edece\u011fimizi derinlemesine inceleyece\u011fiz. Reducer&#8217;lar, Redux uygulaman\u0131z\u0131n mant\u0131\u011f\u0131n\u0131n b\u00fcy\u00fck bir k\u0131sm\u0131n\u0131 bar\u0131nd\u0131rd\u0131\u011f\u0131 i\u00e7in, do\u011fru bir \u015fekilde test edilmeleri uygulaman\u0131z\u0131n g\u00fcvenilirli\u011fi ve s\u00fcrd\u00fcr\u00fclebilirli\u011fi a\u00e7\u0131s\u0131ndan kritik \u00f6neme sahiptir.<\/p>\n<h3>Giri\u015f: Neden Reducer&#8217;lar\u0131 Test Etmeliyiz?<\/h3>\n<p>Redux mimarisinde, uygulaman\u0131n t\u00fcm durumu tek bir merkezi &#8220;store&#8221; i\u00e7inde saklan\u0131r. Bu durum, do\u011frudan de\u011fi\u015ftirilemez; bunun yerine, durumu de\u011fi\u015ftirmek i\u00e7in &#8220;eylemler&#8221; (actions) g\u00f6nderilir. Eylemler, Redux store&#8217;a ula\u015ft\u0131\u011f\u0131nda, &#8220;reducer&#8221; ad\u0131 verilen fonksiyonlar taraf\u0131ndan i\u015flenir. Reducer&#8217;lar, mevcut durumu ve bir eylemi girdi olarak alarak, uygulaman\u0131n yeni durumunu d\u00f6nd\u00fcren saf fonksiyonlard\u0131r.<\/p>\n<p>Reducer&#8217;lar\u0131n test edilmesi, Redux tabanl\u0131 uygulamalar\u0131n geli\u015ftirme s\u00fcrecinde vazge\u00e7ilmez bir ad\u0131md\u0131r. Bunun birka\u00e7 \u00f6nemli nedeni vard\u0131r:<\/p>\n<p>*   <strong>Mant\u0131\u011f\u0131n Do\u011frulu\u011funu Garanti Etmek:<\/strong> Reducer&#8217;lar, uygulaman\u0131z\u0131n durumunun nas\u0131l de\u011fi\u015fece\u011fini tan\u0131mlayan temel i\u015f mant\u0131\u011f\u0131n\u0131 i\u00e7erir. Bu mant\u0131\u011f\u0131n do\u011fru \u00e7al\u0131\u015ft\u0131\u011f\u0131ndan emin olmak, uygulaman\u0131n beklenen \u015fekilde davranmas\u0131n\u0131 sa\u011flar. Testler, her bir eylemin durumu do\u011fru bir \u015fekilde g\u00fcncelledi\u011fini do\u011frular.<br \/>\n*   <strong>Refaktoring G\u00fcvenli\u011fi:<\/strong> Kod taban\u0131n\u0131z\u0131 refakt\u00f6r ederken veya yeni \u00f6zellikler eklerken, mevcut i\u015flevselli\u011fi bozma riski her zaman vard\u0131r. Kapsaml\u0131 reducer testleri, kodunuzda yapt\u0131\u011f\u0131n\u0131z de\u011fi\u015fikliklerin mevcut mant\u0131\u011f\u0131 etkilemedi\u011fini garanti ederek size g\u00fcven verir. Bir testi bozmadan refakt\u00f6r edemiyorsan\u0131z, bu, yapt\u0131\u011f\u0131n\u0131z de\u011fi\u015fikli\u011fin yanl\u0131\u015f oldu\u011fu veya testinizin g\u00fcncellenmesi gerekti\u011fi anlam\u0131na gelir.<br \/>\n*   <strong>Hata Yakalamay\u0131 Kolayla\u015ft\u0131rmak:<\/strong> Reducer testleri, potansiyel hatalar\u0131 geli\u015ftirme s\u00fcrecinin erken a\u015famalar\u0131nda tespit etmeye yard\u0131mc\u0131 olur. Hatalar, \u00fcretime ula\u015fmadan \u00f6nce yakaland\u0131\u011f\u0131nda, d\u00fczeltilmesi \u00e7ok daha kolay ve maliyetsizdir.<br \/>\n*   <strong>Dok\u00fcmantasyon Niteli\u011fi:<\/strong> \u0130yi yaz\u0131lm\u0131\u015f testler, kodun kendisi gibi bir dok\u00fcmantasyon g\u00f6revi g\u00f6r\u00fcr. Bir geli\u015ftirici, bir reducer&#8217;\u0131n ne yapt\u0131\u011f\u0131n\u0131 anlamak istedi\u011finde, ilgili test dosyas\u0131na bakarak farkl\u0131 eylemlerin durumu nas\u0131l etkiledi\u011fini h\u0131zl\u0131ca g\u00f6rebilir.<br \/>\n*   <strong>Saf Fonksiyon Olmalar\u0131 Nedeniyle Kolay Test Edilebilirlik:<\/strong> Reducer&#8217;lar, yan etkileri olmayan (side-effect-free) saf fonksiyonlard\u0131r. Bu \u00f6zellik, onlar\u0131n izole bir \u015fekilde ve \u00f6ng\u00f6r\u00fclebilir bir bi\u00e7imde test edilmesini son derece kolayla\u015ft\u0131r\u0131r. D\u0131\u015f ba\u011f\u0131ml\u0131l\u0131klar\u0131 olmad\u0131\u011f\u0131 i\u00e7in, karma\u015f\u0131k sahteleme (mocking) veya ortam kurulumlar\u0131na genellikle ihtiya\u00e7 duyulmaz.<\/p>\n<p>Bu nedenlerden dolay\u0131, Redux uygulamalar\u0131nda reducer testlerine yeterince zaman ve \u00e7aba ay\u0131rmak, uzun vadede projenin sa\u011fl\u0131\u011f\u0131 ve geli\u015ftirme h\u0131z\u0131na \u00f6nemli katk\u0131 sa\u011flar.<\/p>\n<h3>Redux Reducer&#8217;lar\u0131n\u0131n Temelleri ve Test Edilebilirli\u011fi<\/h3>\n<p>Redux reducer&#8217;lar\u0131, belirli bir imza ve davran\u0131\u015f kurallar\u0131na uyan fonksiyonlard\u0131r. Bu kurallar, reducer&#8217;lar\u0131n test edilebilirli\u011fini do\u011frudan etkiler ve kolayla\u015ft\u0131r\u0131r.<\/p>\n<h4>Reducer Tan\u0131m\u0131 ve Saf Fonksiyon \u00d6zellikleri<\/h4>\n<p>Bir Redux reducer&#8217;\u0131, iki ana arg\u00fcman alan bir fonksiyondur: mevcut durum (state) ve bir eylem (action). Fonksiyonun d\u00f6nd\u00fcrd\u00fc\u011f\u00fc de\u011fer ise uygulaman\u0131n yeni durumudur. \u0130mza \u015fu \u015fekildedir: <code>(state, action) => newState<\/code>.<\/p>\n<p>Reducer&#8217;lar\u0131n en \u00f6nemli \u00f6zelli\u011fi, &#8220;saf fonksiyon&#8221; (pure function) olmalar\u0131d\u0131r. Saf fonksiyonlar, a\u015fa\u011f\u0131daki \u00f6zellikleri ta\u015f\u0131r:<\/p>\n<p>1.  <strong>Ayn\u0131 Girdi \u0130\u00e7in Ayn\u0131 \u00c7\u0131kt\u0131y\u0131 Verir:<\/strong> Bir reducer&#8217;\u0131 ayn\u0131 ba\u015flang\u0131\u00e7 durumu ve ayn\u0131 eylemle birden fazla kez \u00e7a\u011f\u0131rd\u0131\u011f\u0131n\u0131zda, her zaman ayn\u0131 yeni durumu d\u00f6nd\u00fcrmelidir.<br \/>\n2.  <strong>Yan Etki (Side Effect) \u00dcretmez:<\/strong> Saf fonksiyonlar, kendi kapsamlar\u0131 d\u0131\u015f\u0131ndaki herhangi bir \u015feyi de\u011fi\u015ftirmezler. Bu, veritaban\u0131 \u00e7a\u011fr\u0131lar\u0131, API istekleri, dosya okuma\/yazma, DOM manip\u00fclasyonu veya konsola log yazma gibi i\u015flemleri yapmad\u0131klar\u0131 anlam\u0131na gelir. Reducer&#8217;lar sadece yeni bir durum nesnesi olu\u015fturur ve d\u00f6nd\u00fcr\u00fcr.<br \/>\n3.  <strong>Girdi Arg\u00fcmanlar\u0131n\u0131 De\u011fi\u015ftirmez (Immutable):<\/strong> Reducer&#8217;lar, kendilerine gelen <code>state<\/code> veya <code>action<\/code> objelerini do\u011frudan de\u011fi\u015ftirmemelidir. Bunun yerine, mevcut durumdan t\u00fcretilmi\u015f <em>yeni<\/em> bir durum nesnesi olu\u015fturup geri d\u00f6nd\u00fcrmelidirler. Bu ilke, &#8220;immutability&#8221; (de\u011fi\u015fmezlik) olarak bilinir ve Redux&#8217;un temel ta\u015flar\u0131ndan biridir.<\/p>\n<p>Bu saf fonksiyon \u00f6zellikleri, reducer&#8217;lar\u0131n test edilebilirli\u011fini ola\u011fan\u00fcst\u00fc derecede art\u0131r\u0131r. \u00c7\u00fcnk\u00fc:<\/p>\n<p>*   <strong>\u0130zolasyon:<\/strong> Reducer&#8217;lar tamamen izoledir. D\u0131\u015f d\u00fcnyayla etkile\u015fimleri olmad\u0131\u011f\u0131 i\u00e7in, onlar\u0131 test etmek i\u00e7in karma\u015f\u0131k ortam kurulumlar\u0131na veya d\u0131\u015f ba\u011f\u0131ml\u0131l\u0131klar\u0131 sahteleme (mocking) i\u015flemlerine gerek kalmaz. Sadece girdi (state, action) ve beklenen \u00e7\u0131kt\u0131 (newState) ile ilgileniriz.<br \/>\n*   <strong>\u00d6ng\u00f6r\u00fclebilirlik:<\/strong> Ayn\u0131 girdiler her zaman ayn\u0131 \u00e7\u0131kt\u0131y\u0131 \u00fcretece\u011fi i\u00e7in, testler yazmak ve beklenen sonu\u00e7lar\u0131 do\u011frulamak basittir.<br \/>\n*   <strong>Immutability&#8217;nin \u00d6nemi:<\/strong> Durum nesnelerinin de\u011fi\u015ftirilmeden yeni bir kopyas\u0131n\u0131n olu\u015fturulmas\u0131, zaman yolculu\u011fu hata ay\u0131klamas\u0131 (time-travel debugging) gibi Redux&#8217;un geli\u015fmi\u015f \u00f6zelliklerini m\u00fcmk\u00fcn k\u0131lar. Testlerde, durumun ger\u00e7ekten de\u011fi\u015fmez olup olmad\u0131\u011f\u0131n\u0131 kontrol etmek i\u00e7in <code>expect(newState).not.toBe(currentState);<\/code> gibi ifadeler kullanmak \u00f6nemlidir. Bu, JavaScript&#8217;teki nesne referanslar\u0131n\u0131n farkl\u0131 oldu\u011funu do\u011frular, yani yeni bir nesne olu\u015fturulmu\u015ftur.<\/p>\n<h3>Jest ve Enzyme ile Reducer Test Ortam\u0131n\u0131 Kurma<\/h3>\n<p>Bu makale serisinin \u00f6nceki b\u00f6l\u00fcmlerinde Jest ve Enzyme&#8217;nin temel kurulumunu ele alm\u0131\u015ft\u0131k. Reducer testleri i\u00e7in genellikle Enzyme&#8217;ye ihtiya\u00e7 duyulmaz \u00e7\u00fcnk\u00fc reducer&#8217;lar UI bile\u015fenleri de\u011fildir; tamamen JavaScript fonksiyonlar\u0131d\u0131r. Bu nedenle, testlerimizi yazarken sadece Jest&#8217;in g\u00fc\u00e7l\u00fc test \u00e7at\u0131s\u0131ndan faydalanaca\u011f\u0131z.<\/p>\n<h4>Jest Kurulumuna K\u0131sa Bir Hat\u0131rlatma<\/h4>\n<p>E\u011fer projenizde Jest kurulu de\u011filse, a\u015fa\u011f\u0131daki komutla kurabilirsiniz:<\/p>\n<pre><code class=\"language-bash\">npm install --save-dev jest\n<h2>veya<\/h2>\nyarn add --dev jest<\/code><\/pre>\n<p><code>package.json<\/code> dosyan\u0131za bir test beti\u011fi eklemek iyi bir uygulamad\u0131r:<\/p>\n<pre><code class=\"language-json\">{\n  \"scripts\": {\n    \"test\": \"jest\"\n  }\n}<\/code><\/pre>\n<h4>\u00d6rnek Bir Reducer Yap\u0131s\u0131<\/h4>\n<p>\u015eimdi basit bir <code>todoReducer.js<\/code> dosyas\u0131 olu\u015ftural\u0131m:<\/p>\n<pre><code class=\"language-javascript\">\/\/ src\/reducers\/todoReducer.js\n\nconst initialState = {\n  todos: [],\n  filter: 'ALL',\n};\n\nconst todoReducer = (state = initialState, action) => {\n  switch (action.type) {\n    case 'ADD_TODO':\n      return {\n        ...state,\n        todos: [\n          ...state.todos,\n          {\n            id: action.payload.id,\n            text: action.payload.text,\n            completed: false,\n          },\n        ],\n      };\n    case 'TOGGLE_TODO':\n      return {\n        ...state,\n        todos: state.todos.map((todo) =>\n          todo.id === action.payload.id\n            ? { ...todo, completed: !todo.completed }\n            : todo\n        ),\n      };\n    case 'SET_FILTER':\n      return {\n        ...state,\n        filter: action.payload.filter,\n      };\n    case 'REMOVE_TODO':\n      return {\n        ...state,\n        todos: state.todos.filter(todo => todo.id !== action.payload.id)\n      };\n    default:\n      return state;\n  }\n};\n\nexport default todoReducer;<\/code><\/pre>\n<p>Bu reducer&#8217;\u0131 test etmek i\u00e7in, genellikle ayn\u0131 dizinde veya <code>__tests__<\/code> gibi \u00f6zel bir dizinde <code>todoReducer.test.js<\/code> ad\u0131nda bir dosya olu\u015ftururuz.<\/p>\n<pre><code class=\"language-javascript\">\/\/ src\/reducers\/todoReducer.test.js\nimport todoReducer from '.\/todoReducer';\n\ndescribe('todoReducer', () => {\n  \/\/ Test senaryolar\u0131 buraya gelecek\n});<\/code><\/pre>\n<p><code>describe<\/code> blo\u011fu, ilgili testleri grupland\u0131rmak i\u00e7in kullan\u0131l\u0131r. <code>it<\/code> veya <code>test<\/code> fonksiyonlar\u0131 ise her bir bireysel test senaryosunu tan\u0131mlar. Jest&#8217;in <code>expect<\/code> fonksiyonu ile de beklenen sonu\u00e7lar\u0131 do\u011frular\u0131z.<\/p>\n<h3>Temel Reducer Test Senaryolar\u0131<\/h3>\n<p>Reducer&#8217;lar\u0131 test ederken ele almam\u0131z gereken birka\u00e7 temel senaryo vard\u0131r. Bu senaryolar, reducer&#8217;\u0131n\u0131z\u0131n her durumda do\u011fru davrand\u0131\u011f\u0131ndan emin olman\u0131z\u0131 sa\u011flar.<\/p>\n<h4>Ba\u015flang\u0131\u00e7 Durumunu Test Etmek (Initial State)<\/h4>\n<p>Bir reducer&#8217;\u0131n en temel sorumluluklar\u0131ndan biri, <code>state<\/code> arg\u00fcman\u0131 <code>undefined<\/code> oldu\u011funda ba\u015flang\u0131\u00e7 durumunu (initial state) d\u00f6nd\u00fcrmektir. Bu genellikle Redux store ilk olu\u015fturuldu\u011funda veya bir reducer&#8217;\u0131n durumu hen\u00fcz belirlenmedi\u011finde ger\u00e7ekle\u015fir.<\/p>\n<pre><code class=\"language-javascript\">\/\/ src\/reducers\/todoReducer.test.js\nimport todoReducer from '.\/todoReducer';\n\ndescribe('todoReducer', () => {\n  it('ba\u015flang\u0131\u00e7 durumu tan\u0131ml\u0131 de\u011filse, ba\u015flang\u0131\u00e7 durumunu d\u00f6nd\u00fcrmelidir', () => {\n    const expectedInitialState = {\n      todos: [],\n      filter: 'ALL',\n    };\n    \/\/ Redux genellikle '@@INIT' gibi bir eylem t\u00fcr\u00fc g\u00f6nderir\n    \/\/ veya sadece tan\u0131ms\u0131z bir eylem t\u00fcr\u00fc de ayn\u0131 sonucu vermelidir.\n    expect(todoReducer(undefined, { type: '@@INIT' })).toEqual(expectedInitialState);\n    expect(todoReducer(undefined, {})).toEqual(expectedInitialState); \/\/ Bo\u015f bir eylem objesiyle de test edilebilir\n  });\n});<\/code><\/pre>\n<p>Burada, <code>todoReducer<\/code>&#8216;\u0131 <code>undefined<\/code> bir state ve rastgele bir eylemle \u00e7a\u011f\u0131r\u0131yoruz. <code>toEqual<\/code> matcher&#8217;\u0131, nesnelerin derinlemesine e\u015fitli\u011fini kontrol eder, bu da karma\u015f\u0131k durum objeleri i\u00e7in idealdir.<\/p>\n<h4>Tan\u0131ms\u0131z Eylemleri Test Etmek (Unknown Actions)<\/h4>\n<p>Bir reducer, kendisine gelen eylem t\u00fcr\u00fcn\u00fc tan\u0131m\u0131yorsa, mevcut durumu de\u011fi\u015ftirmeden geri d\u00f6nd\u00fcrmelidir. Bu, uygulaman\u0131n durumunun beklenmedik eylemlerle bozulmamas\u0131n\u0131 sa\u011flar.<\/p>\n<pre><code class=\"language-javascript\">\/\/ src\/reducers\/todoReducer.test.js\nimport todoReducer from '.\/todoReducer';\n\ndescribe('todoReducer', () => {\n  \/\/ ... (\u00f6nceki testler)\n\n  it('tan\u0131ms\u0131z bir eylem t\u00fcr\u00fc ile mevcut durumu de\u011fi\u015ftirmeden d\u00f6nd\u00fcrmelidir', () => {\n    const currentState = {\n      todos: [{ id: 1, text: 'Test Todo', completed: false }],\n      filter: 'ALL',\n    };\n    const unknownAction = { type: 'UNKNOWN_ACTION' };\n\n    const newState = todoReducer(currentState, unknownAction);\n\n    expect(newState).toEqual(currentState);\n    \/\/ Immutability kontrol\u00fc: Nesne referans\u0131 ayn\u0131 olmal\u0131, \u00e7\u00fcnk\u00fc durum de\u011fi\u015fmedi.\n    expect(newState).toBe(currentState);\n  });\n});<\/code><\/pre>\n<p>Bu testte, reducer&#8217;\u0131n tan\u0131mad\u0131\u011f\u0131 bir eylem t\u00fcr\u00fc ile \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda mevcut durumu oldu\u011fu gibi geri d\u00f6nd\u00fcrd\u00fc\u011f\u00fcn\u00fc ve hatta nesne referans\u0131n\u0131n bile de\u011fi\u015fmedi\u011fini (\u00e7\u00fcnk\u00fc bir de\u011fi\u015fiklik yap\u0131lmad\u0131) do\u011frular\u0131z.<\/p>\n<h4>Belirli Eylemleri Test Etmek (Specific Actions)<\/h4>\n<p>Bu, reducer testlerinin ana g\u00f6vdesini olu\u015fturur. Her bir tan\u0131ml\u0131 eylem t\u00fcr\u00fc i\u00e7in, reducer&#8217;\u0131n durumu nas\u0131l de\u011fi\u015ftirdi\u011fini do\u011frulamam\u0131z gerekir.<\/p>\n<h5>ADD_TODO Eylemini Test Etmek<\/h5>\n<pre><code class=\"language-javascript\">\/\/ src\/reducers\/todoReducer.test.js\nimport todoReducer from '.\/todoReducer';\n\ndescribe('todoReducer', () => {\n  \/\/ ... (\u00f6nceki testler)\n\n  it('ADD_TODO eylemi ile yeni bir todo eklemelidir', () => {\n    const currentState = {\n      todos: [],\n      filter: 'ALL',\n    };\n    const action = {\n      type: 'ADD_TODO',\n      payload: { id: 1, text: 'Yeni g\u00f6rev' },\n    };\n\n    const newState = todoReducer(currentState, action);\n\n    expect(newState.todos.length).toBe(1);\n    expect(newState.todos[0]).toEqual({\n      id: 1,\n      text: 'Yeni g\u00f6rev',\n      completed: false,\n    });\n    \/\/ Immutability kontrol\u00fc: Yeni bir durum nesnesi d\u00f6nd\u00fcr\u00fclmeli\n    expect(newState).not.toBe(currentState);\n    expect(newState.todos).not.toBe(currentState.todos);\n  });\n\n  it('mevcut todolara yeni bir todo eklemelidir', () => {\n    const currentState = {\n      todos: [{ id: 1, text: 'Mevcut g\u00f6rev', completed: false }],\n      filter: 'ALL',\n    };\n    const action = {\n      type: 'ADD_TODO',\n      payload: { id: 2, text: '\u0130kinci g\u00f6rev' },\n    };\n\n    const newState = todoReducer(currentState, action);\n\n    expect(newState.todos.length).toBe(2);\n    expect(newState.todos[1]).toEqual({\n      id: 2,\n      text: '\u0130kinci g\u00f6rev',\n      completed: false,\n    });\n    expect(newState.todos[0]).toEqual(currentState.todos[0]); \/\/ Mevcut todonun de\u011fi\u015fmedi\u011fini kontrol et\n    expect(newState).not.toBe(currentState);\n    expect(newState.todos).not.toBe(currentState.todos);\n  });\n});<\/code><\/pre>\n<p>Bu \u00f6rnekte, <code>ADD_TODO<\/code> eyleminin hem bo\u015f bir <code>todos<\/code> dizisine hem de mevcut <code>todos<\/code> dizisine nas\u0131l yeni bir \u00f6\u011fe ekledi\u011fini test ediyoruz. Ayr\u0131ca, <code>newState<\/code> ve <code>newState.todos<\/code>&#8216;un <code>currentState<\/code> ve <code>currentState.todos<\/code>&#8216;tan farkl\u0131 referanslara sahip oldu\u011funu do\u011frulayarak immutability&#8217;yi kontrol ediyoruz.<\/p>\n<h5>TOGGLE_TODO Eylemini Test Etmek<\/h5>\n<pre><code class=\"language-javascript\">\/\/ src\/reducers\/todoReducer.test.js\nimport todoReducer from '.\/todoReducer';\n\ndescribe('todoReducer', () => {\n  \/\/ ... (\u00f6nceki testler)\n\n  it('TOGGLE_TODO eylemi ile belirli bir todonun tamamlanma durumunu de\u011fi\u015ftirmelidir', () => {\n    const currentState = {\n      todos: [\n        { id: 1, text: 'G\u00f6rev 1', completed: false },\n        { id: 2, text: 'G\u00f6rev 2', completed: true },\n      ],\n      filter: 'ALL',\n    };\n    const action = {\n      type: 'TOGGLE_TODO',\n      payload: { id: 1 },\n    };\n\n    const newState = todoReducer(currentState, action);\n\n    expect(newState.todos[0].completed).toBe(true);\n    expect(newState.todos[1].completed).toBe(true); \/\/ Di\u011fer todonun de\u011fi\u015fmedi\u011fini kontrol et\n    expect(newState).not.toBe(currentState);\n    expect(newState.todos).not.toBe(currentState.todos);\n  });\n\n  it('var olmayan bir ID i\u00e7in TOGGLE_TODO eylemi ile durumu de\u011fi\u015ftirmemelidir', () => {\n    const currentState = {\n      todos: [{ id: 1, text: 'G\u00f6rev 1', completed: false }],\n      filter: 'ALL',\n    };\n    const action = {\n      type: 'TOGGLE_TODO',\n      payload: { id: 999 }, \/\/ Var olmayan ID\n    };\n\n    const newState = todoReducer(currentState, action);\n\n    expect(newState).toEqual(currentState); \/\/ Durum de\u011fi\u015fmemeli\n    expect(newState).not.toBe(currentState); \/\/ Ancak immutability ilkesi gere\u011fi, todos dizisi map edildi\u011fi i\u00e7in yeni bir dizi referans\u0131 d\u00f6nebilir.\n                                            \/\/ Bu durumda <code>toEqual<\/code> yeterlidir, <code>toBe<\/code> kontrol\u00fc yan\u0131lt\u0131c\u0131 olabilir.\n                                            \/\/ Reducer mant\u0131\u011f\u0131n\u0131za g\u00f6re de\u011fi\u015fir. E\u011fer hi\u00e7bir de\u011fi\u015fiklik yoksa, direkt <code>return state;<\/code> yap\u0131lmas\u0131 daha iyi olurdu.\n                                            \/\/ Mevcut durumda map her zaman yeni bir dizi d\u00f6nd\u00fcr\u00fcr.\n    expect(newState.todos).not.toBe(currentState.todos); \/\/ Dizinin referans\u0131 de\u011fi\u015fmi\u015f olmal\u0131\n  });\n});<\/code><\/pre>\n<p><code>TOGGLE_TODO<\/code> testinde, belirli bir <code>todo<\/code>&#8216;nun <code>completed<\/code> \u00f6zelli\u011finin do\u011fru \u015fekilde de\u011fi\u015fti\u011fini ve di\u011fer <code>todo<\/code>&#8216;lar\u0131n etkilenmedi\u011fini kontrol ediyoruz. Ayr\u0131ca, var olmayan bir ID ile \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda durumun de\u011fi\u015fmedi\u011fini de test etmek \u00f6nemlidir. \u0130mmutability kontrol\u00fc burada biraz daha n\u00fcansl\u0131d\u0131r: <code>map<\/code> fonksiyonu her zaman yeni bir dizi d\u00f6nd\u00fcrd\u00fc\u011f\u00fc i\u00e7in, durum de\u011fi\u015fmese bile <code>newState.todos<\/code>&#8216;un referans\u0131 de\u011fi\u015fecektir. Bu durumda <code>toEqual<\/code> ile i\u00e7erik e\u015fitli\u011fini kontrol etmek daha do\u011fru bir yakla\u015f\u0131md\u0131r.<\/p>\n<h5>SET_FILTER ve REMOVE_TODO Eylemlerini Test Etmek<\/h5>\n<p>Benzer \u015fekilde, di\u011fer eylemler i\u00e7in de testler yazabiliriz:<\/p>\n<pre><code class=\"language-javascript\">\/\/ src\/reducers\/todoReducer.test.js\nimport todoReducer from '.\/todoReducer';\n\ndescribe('todoReducer', () => {\n  \/\/ ... (\u00f6nceki testler)\n\n  it('SET_FILTER eylemi ile filtreyi de\u011fi\u015ftirmelidir', () => {\n    const currentState = {\n      todos: [],\n      filter: 'ALL',\n    };\n    const action = {\n      type: 'SET_FILTER',\n      payload: { filter: 'COMPLETED' },\n    };\n\n    const newState = todoReducer(currentState, action);\n\n    expect(newState.filter).toBe('COMPLETED');\n    expect(newState).not.toBe(currentState);\n  });\n\n  it('REMOVE_TODO eylemi ile belirli bir todoyu kald\u0131rmal\u0131d\u0131r', () => {\n    const currentState = {\n      todos: [\n        { id: 1, text: 'G\u00f6rev 1', completed: false },\n        { id: 2, text: 'G\u00f6rev 2', completed: true },\n      ],\n      filter: 'ALL',\n    };\n    const action = {\n      type: 'REMOVE_TODO',\n      payload: { id: 1 },\n    };\n\n    const newState = todoReducer(currentState, action);\n\n    expect(newState.todos.length).toBe(1);\n    expect(newState.todos[0]).toEqual({ id: 2, text: 'G\u00f6rev 2', completed: true });\n    expect(newState).not.toBe(currentState);\n    expect(newState.todos).not.toBe(currentState.todos);\n  });\n\n  it('var olmayan bir ID i\u00e7in REMOVE_TODO eylemi ile durumu de\u011fi\u015ftirmemelidir', () => {\n    const currentState = {\n      todos: [{ id: 1, text: 'G\u00f6rev 1', completed: false }],\n      filter: 'ALL',\n    };\n    const action = {\n      type: 'REMOVE_TODO',\n      payload: { id: 999 }, \/\/ Var olmayan ID\n    };\n\n    const newState = todoReducer(currentState, action);\n\n    expect(newState).toEqual(currentState);\n    expect(newState).toBe(currentState); \/\/ Hi\u00e7bir de\u011fi\u015fiklik olmad\u0131\u011f\u0131 i\u00e7in referans da ayn\u0131 kalmal\u0131\n  });\n});<\/code><\/pre>\n<p>Bu testlerde de immutability kontrollerini ve beklenen durum de\u011fi\u015fikliklerini do\u011fru bir \u015fekilde yapt\u0131\u011f\u0131m\u0131zdan emin oluyoruz. \u00d6zellikle <code>REMOVE_TODO<\/code>&#8216;nun var olmayan bir ID ile \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda durumu hi\u00e7 de\u011fi\u015ftirmemesi (ve referans\u0131n ayn\u0131 kalmas\u0131) beklenen bir davran\u0131\u015ft\u0131r.<\/p>\n<h3>Asenkron Eylemleri ve Reducer Etkile\u015fimlerini Test Etmek<\/h3>\n<p>Redux reducer&#8217;lar\u0131, tan\u0131m gere\u011fi saf ve senkron fonksiyonlard\u0131r. Bu, reducer&#8217;lar\u0131n do\u011frudan asenkron i\u015flemleri (API \u00e7a\u011fr\u0131lar\u0131, zamanlay\u0131c\u0131lar vb.) ele almad\u0131\u011f\u0131 anlam\u0131na gelir. Asenkron mant\u0131k, genellikle Redux Thunk, Redux Saga veya Redux Observable gibi ara yaz\u0131l\u0131mlar (middleware) arac\u0131l\u0131\u011f\u0131yla y\u00f6netilir.<\/p>\n<p>Bu ara yaz\u0131l\u0131mlar, asenkron bir i\u015flem ba\u015flad\u0131\u011f\u0131nda (\u00f6rn. <code>FETCH_USERS_REQUEST<\/code>), ba\u015far\u0131l\u0131 oldu\u011funda (<code>FETCH_USERS_SUCCESS<\/code>) veya ba\u015far\u0131s\u0131z oldu\u011funda (<code>FETCH_USERS_FAILURE<\/code>) farkl\u0131 senkron eylemler g\u00f6nderir. Reducer&#8217;lar\u0131n g\u00f6revi, bu senkron eylemleri dinlemek ve duruma uygun de\u011fi\u015fiklikleri uygulamakt\u0131r.<\/p>\n<p>Dolay\u0131s\u0131yla, reducer testleri, asenkron i\u015flemin kendisini de\u011fil, asenkron i\u015flem sonucunda g\u00f6nderilen <em>senkron<\/em> eylemlerin durumu nas\u0131l etkiledi\u011fini do\u011frulamal\u0131d\u0131r.<\/p>\n<p>\u00d6rne\u011fin, kullan\u0131c\u0131lar\u0131 getiren bir API \u00e7a\u011fr\u0131n\u0131z oldu\u011funu varsayal\u0131m. Bu i\u015flem \u00fc\u00e7 a\u015famal\u0131 bir dizi eylem tetikleyebilir:<\/p>\n<p>*   <code>FETCH_USERS_REQUEST<\/code>: Kullan\u0131c\u0131lar y\u00fcklenmeye ba\u015fland\u0131. Durumda bir <code>isLoading: true<\/code> bayra\u011f\u0131 ayarlanabilir.<br \/>\n*   <code>FETCH_USERS_SUCCESS<\/code>: Kullan\u0131c\u0131lar ba\u015far\u0131yla y\u00fcklendi. <code>users<\/code> dizisi g\u00fcncellenir, <code>isLoading: false<\/code> olur.<br \/>\n*   <code>FETCH_USERS_FAILURE<\/code>: Kullan\u0131c\u0131lar y\u00fcklenirken bir hata olu\u015ftu. <code>error<\/code> mesaj\u0131 ayarlan\u0131r, <code>isLoading: false<\/code> olur.<\/p>\n<p>Reducer&#8217;\u0131n\u0131z bu eylemleri a\u015fa\u011f\u0131daki gibi i\u015fleyebilir:<\/p>\n<pre><code class=\"language-javascript\">\/\/ src\/reducers\/userReducer.js\nconst initialUserState = {\n  users: [],\n  isLoading: false,\n  error: null,\n};\n\nconst userReducer = (state = initialUserState, action) => {\n  switch (action.type) {\n    case 'FETCH_USERS_REQUEST':\n      return { ...state, isLoading: true, error: null };\n    case 'FETCH_USERS_SUCCESS':\n      return { ...state, isLoading: false, users: action.payload.users };\n    case 'FETCH_USERS_FAILURE':\n      return { ...state, isLoading: false, error: action.payload.error };\n    default:\n      return state;\n  }\n};\nexport default userReducer;<\/code><\/pre>\n<p>Bu reducer&#8217;\u0131 test ederken, her bir senkron eylemin durum \u00fczerindeki etkisini ayr\u0131 ayr\u0131 do\u011frular\u0131z:<\/p>\n<pre><code class=\"language-javascript\">\/\/ src\/reducers\/userReducer.test.js\nimport userReducer from '.\/userReducer';\n\ndescribe('userReducer', () => {\n  it('FETCH_USERS_REQUEST eylemi ile isLoading durumunu true yapmal\u0131 ve hatay\u0131 temizlemelidir', () => {\n    const currentState = { users: [], isLoading: false, error: 'some error' };\n    const action = { type: 'FETCH_USERS_REQUEST' };\n    const newState = userReducer(currentState, action);\n\n    expect(newState.isLoading).toBe(true);\n    expect(newState.error).toBeNull();\n    expect(newState.users).toEqual(currentState.users); \/\/ Di\u011fer k\u0131s\u0131mlar de\u011fi\u015fmemeli\n  });\n\n  it('FETCH_USERS_SUCCESS eylemi ile kullan\u0131c\u0131lar\u0131 y\u00fcklemeli ve isLoading durumunu false yapmal\u0131d\u0131r', () => {\n    const currentState = { users: [], isLoading: true, error: null };\n    const fetchedUsers = [{ id: 1, name: 'Alice' }];\n    const action = { type: 'FETCH_USERS_SUCCESS', payload: { users: fetchedUsers } };\n    const newState = userReducer(currentState, action);\n\n    expect(newState.isLoading).toBe(false);\n    expect(newState.users).toEqual(fetchedUsers);\n    expect(newState.error).toBeNull();\n  });\n\n  it('FETCH_USERS_FAILURE eylemi ile hatay\u0131 ayarlamal\u0131 ve isLoading durumunu false yapmal\u0131d\u0131r', () => {\n    const currentState = { users: [], isLoading: true, error: null };\n    const errorMessage = 'Network error';\n    const action = { type: 'FETCH_USERS_FAILURE', payload: { error: errorMessage } };\n    const newState = userReducer(currentState, action);\n\n    expect(newState.isLoading).toBe(false);\n    expect(newState.error).toBe(errorMessage);\n    expect(newState.users).toEqual(currentState.users);\n  });\n});<\/code><\/pre>\n<p>G\u00f6rd\u00fc\u011f\u00fcn\u00fcz gibi, reducer testleri yaln\u0131zca senkron durum ge\u00e7i\u015flerine odaklan\u0131r. Asenkron mant\u0131\u011f\u0131n kendisini (\u00f6rne\u011fin, bir thunk&#8217;\u0131n do\u011fru API \u00e7a\u011fr\u0131s\u0131n\u0131 yap\u0131p yapmad\u0131\u011f\u0131n\u0131) test etmek i\u00e7in farkl\u0131 stratejiler (middleware testleri) gereklidir, ancak bu, reducer testlerinin kapsam\u0131 d\u0131\u015f\u0131ndad\u0131r.<\/p>\n<h3>Ger\u00e7ek D\u00fcnya Senaryolar\u0131 ve \u0130leri D\u00fczey Test Teknikleri<\/h3>\n<p>Ger\u00e7ek d\u00fcnya Redux uygulamalar\u0131 genellikle daha karma\u015f\u0131k durum yap\u0131lar\u0131na ve daha \u00e7e\u015fitli eylem t\u00fcrlerine sahiptir. Bu t\u00fcr senaryolarda reducer testlerini daha etkili hale getirmek i\u00e7in baz\u0131 ileri d\u00fczey teknikler ve yakla\u015f\u0131mlar mevcuttur.<\/p>\n<h4>Birden Fazla Eylem T\u00fcr\u00fcn\u00fc Test Etmek<\/h4>\n<p>Baz\u0131 durumlarda, bir reducer&#8217;\u0131n durumu farkl\u0131 eylem t\u00fcrlerinin ard\u0131\u015f\u0131k \u00e7a\u011fr\u0131lar\u0131yla nas\u0131l de\u011fi\u015fti\u011fini test etmek isteyebilirsiniz. Ancak, her testin izole olmas\u0131 gerekti\u011fi i\u00e7in, genellikle her eylem t\u00fcr\u00fcn\u00fc ayr\u0131 ayr\u0131 test etmek daha iyidir. E\u011fer bir eylemin sonucu di\u011fer bir eylemin ba\u015flang\u0131\u00e7 durumu olacaksa, bunu test i\u00e7inde <code>currentState<\/code> olarak tan\u0131mlayarak yapabilirsiniz.<\/p>\n<h4>Karma\u015f\u0131k Durum Yap\u0131lar\u0131n\u0131 Test Etmek (Nested States)<\/h4>\n<p>Uygulaman\u0131z b\u00fcy\u00fcd\u00fck\u00e7e, Redux durumunuz i\u00e7 i\u00e7e ge\u00e7mi\u015f objeler ve diziler i\u00e7erebilir. Bu t\u00fcr durumlar\u0131 g\u00fcncellerken immutability&#8217;yi korumak kritik \u00f6neme sahiptir. JavaScript&#8217;in spread operat\u00f6r\u00fc (<code>...<\/code>) veya Immer gibi yard\u0131mc\u0131 k\u00fct\u00fcphaneler bu konuda size yard\u0131mc\u0131 olabilir. Testlerde, bu karma\u015f\u0131k yap\u0131lar\u0131n do\u011fru bir \u015fekilde g\u00fcncellendi\u011fini ve de\u011fi\u015fmeyen k\u0131s\u0131mlar\u0131n\u0131n da bozulmad\u0131\u011f\u0131n\u0131 do\u011frulamak i\u00e7in <code>toEqual<\/code> matcher&#8217;\u0131 \u00f6nemlidir.<\/p>\n<p>\u00d6rne\u011fin, bir kullan\u0131c\u0131n\u0131n profil bilgilerini g\u00fcncelleyen bir reducer:<\/p>\n<pre><code class=\"language-javascript\">\/\/ src\/reducers\/profileReducer.js\nconst initialProfileState = {\n  user: {\n    id: null,\n    name: '',\n    email: '',\n    address: {\n      street: '',\n      city: '',\n    },\n  },\n  isEditing: false,\n};\n\nconst profileReducer = (state = initialProfileState, action) => {\n  switch (action.type) {\n    case 'UPDATE_USER_NAME':\n      return {\n        ...state,\n        user: {\n          ...state.user,\n          name: action.payload.name,\n        },\n      };\n    case 'UPDATE_USER_ADDRESS_CITY':\n      return {\n        ...state,\n        user: {\n          ...state.user,\n          address: {\n            ...state.user.address,\n            city: action.payload.city,\n          },\n        },\n      };\n    \/\/ ... di\u011fer eylemler\n    default:\n      return state;\n  }\n};\nexport default profileReducer;<\/code><\/pre>\n<p>Testi:<\/p>\n<pre><code class=\"language-javascript\">\/\/ src\/reducers\/profileReducer.test.js\nimport profileReducer from '.\/profileReducer';\n\ndescribe('profileReducer', () => {\n  const initialProfileState = {\n    user: {\n      id: 1,\n      name: 'John Doe',\n      email: 'john@example.com',\n      address: {\n        street: '123 Main St',\n        city: 'Anytown',\n      },\n    },\n    isEditing: false,\n  };\n\n  it('UPDATE_USER_NAME eylemi ile kullan\u0131c\u0131n\u0131n ad\u0131n\u0131 g\u00fcncellemelidir', () => {\n    const action = { type: 'UPDATE_USER_NAME', payload: { name: 'Jane Doe' } };\n    const newState = profileReducer(initialProfileState, action);\n\n    expect(newState.user.name).toBe('Jane Doe');\n    expect(newState.user.email).toBe(initialProfileState.user.email); \/\/ Di\u011fer alanlar de\u011fi\u015fmemeli\n    expect(newState.user.address).toEqual(initialProfileState.user.address); \/\/ \u0130\u00e7 i\u00e7e nesneler de de\u011fi\u015fmemeli\n    expect(newState).not.toBe(initialProfileState);\n    expect(newState.user).not.toBe(initialProfileState.user);\n    expect(newState.user.address).toBe(initialProfileState.user.address); \/\/ Adres nesnesinin referans\u0131 de\u011fi\u015fmemeli\n  });\n\n  it('UPDATE_USER_ADDRESS_CITY eylemi ile kullan\u0131c\u0131n\u0131n adresindeki \u015fehri g\u00fcncellemelidir', () => {\n    const action = { type: 'UPDATE_USER_ADDRESS_CITY', payload: { city: 'New City' } };\n    const newState = profileReducer(initialProfileState, action);\n\n    expect(newState.user.address.city).toBe('New City');\n    expect(newState.user.address.street).toBe(initialProfileState.user.address.street); \/\/ Di\u011fer adres alanlar\u0131 de\u011fi\u015fmemeli\n    expect(newState.user.name).toBe(initialProfileState.user.name); \/\/ Kullan\u0131c\u0131 ad\u0131 de\u011fi\u015fmemeli\n    expect(newState).not.toBe(initialProfileState);\n    expect(newState.user).not.toBe(initialProfileState.user);\n    expect(newState.user.address).not.toBe(initialProfileState.user.address); \/\/ Adres nesnesinin referans\u0131 de\u011fi\u015fmeli\n  });\n});<\/code><\/pre>\n<p>Bu testlerde, derinlemesine nesnelerin nas\u0131l g\u00fcncellendi\u011fini ve immutability kurallar\u0131n\u0131n nas\u0131l uyguland\u0131\u011f\u0131n\u0131 g\u00f6steriyoruz. <code>expect(newState.user.address).toBe(initialProfileState.user.address);<\/code> gibi kontroller, g\u00fcncellenmeyen alt nesnelerin referanslar\u0131n\u0131n ayn\u0131 kald\u0131\u011f\u0131n\u0131 do\u011frulamak i\u00e7in \u00f6nemlidir.<\/p>\n<h4>Test Ortam\u0131n\u0131 Haz\u0131rlama ve Temizleme (beforeEach, afterEach)<\/h4>\n<p>Birden fazla test senaryosunda ayn\u0131 ba\u015flang\u0131\u00e7 durumunu kullan\u0131yorsan\u0131z, Jest&#8217;in <code>beforeEach<\/code> veya <code>beforeAll<\/code> kancalar\u0131n\u0131 kullanarak her testten \u00f6nce veya t\u00fcm testlerden \u00f6nce ortak bir ba\u015flang\u0131\u00e7 durumu tan\u0131mlayabilirsiniz.<\/p>\n<pre><code class=\"language-javascript\">\/\/ src\/reducers\/todoReducer.test.js\nimport todoReducer from '.\/todoReducer';\n\ndescribe('todoReducer', () => {\n  let initialTodoState; \/\/ Her test i\u00e7in s\u0131f\u0131rlanacak\n\n  beforeEach(() => {\n    initialTodoState = {\n      todos: [],\n      filter: 'ALL',\n    };\n  });\n\n  it('ba\u015flang\u0131\u00e7 durumu tan\u0131ml\u0131 de\u011filse, ba\u015flang\u0131\u00e7 durumunu d\u00f6nd\u00fcrmelidir', () => {\n    expect(todoReducer(undefined, { type: '@@INIT' })).toEqual(initialTodoState);\n  });\n\n  it('ADD_TODO eylemi ile yeni bir todo eklemelidir', () => {\n    const action = {\n      type: 'ADD_TODO',\n      payload: { id: 1, text: 'Yeni g\u00f6rev' },\n    };\n    const newState = todoReducer(initialTodoState, action); \/\/ beforeEach'ten gelen state'i kullan\n    expect(newState.todos.length).toBe(1);\n  });\n  \/\/ ... di\u011fer testler\n});<\/code><\/pre>\n<p><code>beforeEach<\/code>, her <code>it<\/code> blo\u011fundan \u00f6nce \u00e7al\u0131\u015f\u0131r ve her testin temiz bir ba\u015flang\u0131\u00e7 durumuyla ba\u015flamas\u0131n\u0131 sa\u011flar. Bu, testlerin birbirinden ba\u011f\u0131ms\u0131z olmas\u0131n\u0131 garanti eder.<\/p>\n<h3>Test Kapsam\u0131 (Test Coverage) ve En \u0130yi Uygulamalar<\/h3>\n<p>Reducer testlerini yazarken, sadece testlerin ge\u00e7mesini sa\u011flamakla kalmay\u0131p, ayn\u0131 zamanda kodunuzun yeterince kapsand\u0131\u011f\u0131ndan da emin olmak \u00f6nemlidir.<\/p>\n<h4>Test Kapsam\u0131 (Test Coverage)<\/h4>\n<p>Jest, yerle\u015fik test kapsam\u0131 raporlama \u00f6zelli\u011fine sahiptir. <code>jest --coverage<\/code> komutunu \u00e7al\u0131\u015ft\u0131rarak, hangi kod sat\u0131rlar\u0131n\u0131n testler taraf\u0131ndan \u00e7al\u0131\u015ft\u0131r\u0131ld\u0131\u011f\u0131n\u0131 g\u00f6steren ayr\u0131nt\u0131l\u0131 bir rapor alabilirsiniz.<\/p>\n<pre><code class=\"language-bash\">npm test -- --coverage\n<h2>veya<\/h2>\nyarn test --coverage<\/code><\/pre>\n<p>Bu rapor, test edilmemi\u015f kod yollar\u0131n\u0131 (\u00f6rne\u011fin, bir <code>switch<\/code> ifadesindeki bir <code>case<\/code> blo\u011fu veya bir <code>if<\/code> ifadesinin <code>else<\/code> dal\u0131) belirlemenize yard\u0131mc\u0131 olur. %100 kod kapsam\u0131 her zaman %100 hata ay\u0131klama garantisi vermez, ancak mant\u0131\u011f\u0131n\u0131z\u0131n her par\u00e7as\u0131n\u0131n en az bir kez \u00e7al\u0131\u015ft\u0131r\u0131ld\u0131\u011f\u0131n\u0131 g\u00f6sterir ve g\u00fcvenilir bir ba\u015flang\u0131\u00e7 noktas\u0131d\u0131r.<\/p>\n<h4>En \u0130yi Uygulamalar<\/h4>\n<p>*   <strong>Her <code>case<\/code> Statement&#8217;\u0131 Test Edin:<\/strong> Reducer&#8217;\u0131n\u0131zdaki her <code>switch<\/code> ifadesinin her <code>case<\/code> blo\u011funu ayr\u0131 ayr\u0131 test etti\u011finizden emin olun.<br \/>\n*   <strong>Her <code>if<\/code>\/<code>else<\/code> Dal\u0131n\u0131 Test Edin:<\/strong> Reducer&#8217;\u0131n\u0131zda ko\u015fullu mant\u0131k (if\/else) varsa, her iki dal\u0131n da test edildi\u011fini do\u011frulay\u0131n.<br \/>\n*   <strong>Testlerin H\u0131zl\u0131 Olmas\u0131:<\/strong> Reducer testleri, UI bile\u015feni testlerine veya entegrasyon testlerine g\u00f6re \u00e7ok daha h\u0131zl\u0131 olmal\u0131d\u0131r. Bu h\u0131z, geli\u015ftirme d\u00f6ng\u00fcs\u00fcn\u00fc h\u0131zland\u0131r\u0131r.<br \/>\n*   <strong>Anlaml\u0131 Test \u0130simleri Kullan\u0131n:<\/strong> <code>it('should add a todo', ...)<\/code> gibi a\u00e7\u0131klay\u0131c\u0131 test isimleri, test raporlar\u0131n\u0131 okurken veya bir test ba\u015far\u0131s\u0131z oldu\u011funda neyin yanl\u0131\u015f gitti\u011fini anlaman\u0131za yard\u0131mc\u0131 olur.<br \/>\n*   <strong>Tek Bir \u015eeyi Test Edin (Arrange-Act-Assert):<\/strong> Her testin tek bir belirli davran\u0131\u015f\u0131 veya durum ge\u00e7i\u015fini do\u011frulamaya odaklanmas\u0131 iyi bir uygulamad\u0131r.<br \/>\n    *   <strong>Arrange (Haz\u0131rl\u0131k):<\/strong> Test i\u00e7in gerekli ba\u015flang\u0131\u00e7 durumunu ve eylemi ayarlay\u0131n.<br \/>\n    *   <strong>Act (Eylem):<\/strong> Reducer&#8217;\u0131 bu durum ve eylemle \u00e7a\u011f\u0131r\u0131n.<br \/>\n    *   <strong>Assert (Do\u011frulama):<\/strong> Yeni durumun beklenen sonu\u00e7la e\u015fle\u015fti\u011fini do\u011frulay\u0131n.<br \/>\n*   <strong>Mocking&#8217;e Gerek Yok:<\/strong> Reducer&#8217;lar saf fonksiyonlar oldu\u011fu i\u00e7in, genellikle d\u0131\u015f ba\u011f\u0131ml\u0131l\u0131klar\u0131 sahteleme (mocking) ihtiyac\u0131 duymazs\u0131n\u0131z. Bu, testleri daha basit ve daha g\u00fcvenilir hale getirir.<br \/>\n*   <strong>Immutability Kontrol\u00fc:<\/strong> <code>toEqual<\/code> ile i\u00e7erik e\u015fitli\u011fini kontrol etmenin yan\u0131 s\u0131ra, <code>not.toBe<\/code> veya <code>toBe<\/code> ile nesne referanslar\u0131n\u0131n do\u011fru \u015fekilde de\u011fi\u015fip de\u011fi\u015fmedi\u011fini kontrol etmek, immutability kurallar\u0131n\u0131 peki\u015ftirir.<\/p>\n<h3>Sonu\u00e7<\/h3>\n<p>Redux reducer&#8217;lar\u0131n\u0131 Jest ile test etmek, Redux tabanl\u0131 uygulamalar\u0131n geli\u015ftirme s\u00fcrecinde temel ve kritik bir ad\u0131md\u0131r. Reducer&#8217;lar\u0131n saf fonksiyon do\u011fas\u0131, onlar\u0131 son derece test edilebilir k\u0131lar ve bu da uygulaman\u0131z\u0131n durum y\u00f6netim mant\u0131\u011f\u0131n\u0131n do\u011frulu\u011funu ve g\u00fcvenilirli\u011fini garanti etmenizi sa\u011flar.<\/p>\n<p>Bu makalede, reducer testlerinin neden bu kadar \u00f6nemli oldu\u011funu, ba\u015flang\u0131\u00e7 durumu, tan\u0131ms\u0131z eylemler ve belirli eylemler gibi temel senaryolar\u0131 nas\u0131l ele alaca\u011f\u0131m\u0131z\u0131, asenkron eylemlerin reducer testleri \u00fczerindeki dolayl\u0131 etkilerini ve karma\u015f\u0131k durum yap\u0131lar\u0131n\u0131 test etmek i\u00e7in ileri d\u00fczey teknikleri inceledik. Ayr\u0131ca, test kapsam\u0131n\u0131n \u00f6nemi ve reducer testleri i\u00e7in en iyi uygulamalar hakk\u0131nda da konu\u015ftuk.<\/p>\n<p>Kapsaml\u0131 reducer testleri yazarak, uygulaman\u0131z\u0131n temel i\u015f mant\u0131\u011f\u0131n\u0131n sa\u011flam oldu\u011fundan emin olabilir, gelecekteki de\u011fi\u015fiklikler i\u00e7in g\u00fcvenli bir zemin olu\u015fturabilir ve geli\u015ftirme s\u00fcrecinizin genel kalitesini art\u0131rabilirsiniz. Bu, Redux uygulaman\u0131z\u0131n sa\u011flam bir temel \u00fczerine in\u015fa edildi\u011fini bilerek, di\u011fer test t\u00fcrlerine (bile\u015fen testleri, entegrasyon testleri vb.) ge\u00e7i\u015f yapman\u0131za olanak tan\u0131r.<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"React\/Redux Uygulamalar\u0131n\u0131 Jest ve Enzyme ile Test Etmek &#8211; B\u00f6l\u00fcm 4: Redux Reducer&#8217;lar\u0131n\u0131 Test Etmek\nRedux, modern React uygulamalar\u0131nda durum","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":[128],"tags":[],"class_list":{"0":"post-36449","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-react","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>React\/Redux Uygulamalar\u0131n\u0131 Jest ve Enzyme ile Test Etmek - B\u00f6l\u00fcm 4: Redux Reducer&#039;lar\u0131n\u0131 Test Etmek - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\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\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"React\/Redux Uygulamalar\u0131n\u0131 Jest ve Enzyme ile Test Etmek - B\u00f6l\u00fcm 4: Redux Reducer&#039;lar\u0131n\u0131 Test Etmek\" \/>\n<meta property=\"og:description\" content=\"React\/Redux Uygulamalar\u0131n\u0131 Jest ve Enzyme ile Test Etmek - B\u00f6l\u00fcm 4: Redux Reducer&#039;lar\u0131n\u0131 Test Etmek Redux, modern React uygulamalar\u0131nda durum\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-12-17T18:41:01+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=\"21 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"React\/Redux Uygulamalar\u0131n\u0131 Jest ve Enzyme ile Test Etmek &#8211; B\u00f6l\u00fcm 4: Redux Reducer&#8217;lar\u0131n\u0131 Test Etmek\",\"datePublished\":\"2025-12-17T18:41:01+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/\"},\"wordCount\":2707,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"React\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/\",\"name\":\"React\/Redux Uygulamalar\u0131n\u0131 Jest ve Enzyme ile Test Etmek - B\u00f6l\u00fcm 4: Redux Reducer'lar\u0131n\u0131 Test Etmek - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-12-17T18:41:01+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"React\/Redux Uygulamalar\u0131n\u0131 Jest ve Enzyme ile Test Etmek &#8211; B\u00f6l\u00fcm 4: Redux Reducer&#8217;lar\u0131n\u0131 Test Etmek\"}]},{\"@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":"React\/Redux Uygulamalar\u0131n\u0131 Jest ve Enzyme ile Test Etmek - B\u00f6l\u00fcm 4: Redux Reducer'lar\u0131n\u0131 Test Etmek - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","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\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/","og_locale":"tr_TR","og_type":"article","og_title":"React\/Redux Uygulamalar\u0131n\u0131 Jest ve Enzyme ile Test Etmek - B\u00f6l\u00fcm 4: Redux Reducer'lar\u0131n\u0131 Test Etmek","og_description":"React\/Redux Uygulamalar\u0131n\u0131 Jest ve Enzyme ile Test Etmek - B\u00f6l\u00fcm 4: Redux Reducer'lar\u0131n\u0131 Test Etmek Redux, modern React uygulamalar\u0131nda durum","og_url":"https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-12-17T18:41:01+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"21 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"React\/Redux Uygulamalar\u0131n\u0131 Jest ve Enzyme ile Test Etmek &#8211; B\u00f6l\u00fcm 4: Redux Reducer&#8217;lar\u0131n\u0131 Test Etmek","datePublished":"2025-12-17T18:41:01+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/"},"wordCount":2707,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["React"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/","url":"https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/","name":"React\/Redux Uygulamalar\u0131n\u0131 Jest ve Enzyme ile Test Etmek - B\u00f6l\u00fcm 4: Redux Reducer'lar\u0131n\u0131 Test Etmek - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-12-17T18:41:01+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/react-redux-uygulamalarini-jest-ve-enzyme-ile-test-etmek-bolum-4-redux-reducerlarini-test-etmek\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"React\/Redux Uygulamalar\u0131n\u0131 Jest ve Enzyme ile Test Etmek &#8211; B\u00f6l\u00fcm 4: Redux Reducer&#8217;lar\u0131n\u0131 Test Etmek"}]},{"@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\/36449","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=36449"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/36449\/revisions"}],"predecessor-version":[{"id":36450,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/36449\/revisions\/36450"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=36449"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=36449"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=36449"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}