StoryDecember 17, 20253 min read

🚨 Mocking Network Failures, Retries & Edge Cases in Jest

It can mock storage, fake events, spy on functions, and even travel through time.


🚨 Mocking Network Failures, Retries & Edge Cases in Jest

Image generated by Author usingĀ ChatGPT

🚧 When the Internet Betrays You

Our Expense Tracker is becoming smart.

It can mock storage, fake events, spy on functions, and even travel through time.

But there is one thing it still cannot control.

One thing that has embarrassed every developer at least once:

šŸ‘‰ The Internet.

Yesā€Šā€”ā€Šthe same network that works perfectly

until you’re showing your feature to your team…

and suddenly the API returns:

ā€œNetwork Errorā€
ā€œTimeoutā€

ā€œUnexpected token < in JSON at position 0ā€

Your soul leaves your body.

Your teammates stare.

You whisper:

ā€œBut… but this worked yesterdayā€¦ā€

Testing MUST simulate this pain.

Because the real world will definitely simulate it for you later.


šŸ’” Why Network Failures FeelĀ Personal

Image generated by Author usingĀ ChatGPT

When your code fails, you blame yourself.

When the network fails, you blame life.

Everyone has seen:

  • āš ļø Slow responses
  • āŒ Random 500 errors
  • šŸ” Infinite loading spinners
  • 🧨 ā€œWorks on my machineā€ moments
  • šŸ§Ÿā€ā™‚ļø API suddenly returning HTML instead of JSON
  • 🧊 Freeze → retry → freeze → retry

All of this is deeply relatable.

This is why mocking failures keeps readers hookedā€Šā€”ā€Šthey’ve lived this suffering.


🧪 Step 1ā€Šā€”ā€ŠThe Expense Tracker’s ā€œRetryĀ Logicā€

Let’s give our app a new ability:

Try again when the API fails.

šŸ“ fetchRetry.js

const axios = require(&#x27;axios&#x27;);

exports.fetchExpensesWithRetry = async (url, attempts = 3) => {
  for (let i = 0; i < attempts; i++) {
    try {
      const res = await axios.get(url);
      return res.data;
    } catch (err) {
      if (i === attempts - 1) throw err;
    }
  }
};

If the API works → great.

If it fails → try again.

If it always fails → cry.


āš™ļø Step 2ā€Šā€”ā€ŠMocking Failure → Success

šŸ“ fetchRetry.test.js

jest.mock(&#x27;axios&#x27;);
const axios = require(&#x27;axios&#x27;);
const { fetchExpensesWithRetry } = require(&#x27;./fetchRetry&#x27;);

test(&#x27;should retry once and succeed&#x27;, async () => {
  axios.get
    .mockRejectedValueOnce(new Error(&#x27;Network Error&#x27;))
    .mockResolvedValueOnce({ data: [{ id: 1, amount: 500 }] });

  const result = await fetchExpensesWithRetry(&#x27;/expenses&#x27;);

  expect(axios.get).toHaveBeenCalledTimes(2);
  expect(result.length).toBe(1);
});

We fake suffering…

so our users don’t have to.


āš ļø Step 3ā€Šā€”ā€ŠMocking Permanent Failure

Some APIs never want to work.

Like gym membershipsā€Šā€”ā€Šfull of hope, zero results.

test(&#x27;should fail after max retries&#x27;, async () => {
  axios.get.mockRejectedValue(new Error(&#x27;Server Down&#x27;));

  await expect(fetchExpensesWithRetry(&#x27;/expenses&#x27;))
    .rejects.toThrow(&#x27;Server Down&#x27;);

  expect(axios.get).toHaveBeenCalledTimes(3);
});

Now your tests don’t just celebrate success.

They respect failure.


🐌 Step 4ā€Šā€”ā€ŠMocking Slow Responses (Timers + Promises)

Sometimes your API responds so slowly

that you begin reevaluating your career choices.

We simulate that:

jest.useFakeTimers();

axios.get.mockImplementation(() =>
  new Promise(resolve => {
    setTimeout(() => resolve({ data: [] }), 3000);
  })
);

jest.runAllTimers();

Three seconds gone in one millisecond.

If only life worked like Jest.


🧩 Step 5ā€Šā€”ā€ŠMocking Weird/Broken Responses

Let’s simulate the things that cause dev trauma:

Empty data

axios.get.mockResolvedValue({ data: [] });

Null data

axios.get.mockResolvedValue({ data: null });

Corrupted JSON

axios.get.mockResolvedValue({ data: "ThisIsNotJSONBro" });

Your tests should see all of this.

Because your users definitely will.


āœ… SUMMARY

Image generated by Author usingĀ ChatGPT

Today our Expense Tracker became a warrior.

It learned to survive unpredictable network chaos.

We mastered:
Ā šŸ”„ Mocking API failures
Ā šŸ” Mocking retries
 🐢 Mocking slow responses
 🧨 Mocking corrupted responses
 🚫 Mocking permanent failure

Your tests no longer trust the internet.

They trust YOU.

Next post → Mocking Permissions, Sensors & Device Behaviors
(This one is MASSIVE for React Native devs.)

Thanks forĀ reading.

If this added value, follow me for more clear and practical posts.
— Alkesh Jethava