100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Testing

Mocking HTTP Requests

Learn how to mock network calls in Jest tests using axios/fetch stubs, interceptor libraries like nock and msw, and how to simulate error and timeout scenarios.

MockingIntermediate10 min readJul 10, 2026
Analogies

Why Mock HTTP Calls in Tests?

Unit and integration tests that hit a real API are slow, flaky when the network or third-party service is down, and can hit rate limits or incur cost on paid endpoints; they also make test outcomes depend on external data that can change over time. Mocking HTTP requests removes the real network from the equation entirely, letting you assert on exactly how your code handles a given response shape, including edge cases like empty arrays or malformed payloads that would be hard to reliably reproduce against a live service.

🏏

Cricket analogy: Simulating a rain-affected match on a practice ground instead of waiting for real weather mirrors mocking HTTP requests to avoid network flakiness and unpredictable delays in tests.

Mocking fetch and axios Directly

For axios, jest.mock('axios') combined with axios.get.mockResolvedValueOnce({ data: {...} }) is the most direct approach, letting you configure exactly what the client 'receives' back per test. For the native fetch API, since it's a global rather than an importable module, you typically assign global.fetch = jest.fn() and configure it to resolve with an object shaped like a real Response — including ok, status, and a json() method returning a Promise — since your code likely calls response.json() to parse the body.

🏏

Cricket analogy: Scripting a scoreboard operator to always display 'India 250/4' regardless of the actual live feed mirrors mocking axios.get to always resolve with a fixed score payload.

javascript
import { rest } from 'msw';
import { setupServer } from 'msw/node';

const server = setupServer(
  rest.get('/api/user/:id', (req, res, ctx) => {
    return res(ctx.status(200), ctx.json({ id: 1, name: 'Ada' }));
  })
);

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

test('fetches a user successfully', async () => {
  const user = await fetchUser(1);
  expect(user.name).toBe('Ada');
});

Using Interceptor Libraries: nock and msw

nock intercepts outgoing HTTP requests at Node's http/https module level, which is powerful because it works regardless of which HTTP client library your code uses internally — you don't need to know or mock axios versus fetch specifically, just declare the expected request and response. msw (Mock Service Worker) takes a similar network-level interception approach but works in both Node (via setupServer) and real browsers (via a Service Worker), meaning application code makes genuinely unmodified fetch/axios calls that are intercepted transparently, which many teams prefer because it keeps tests closer to production behavior.

🏏

Cricket analogy: Using a broadcast delay buffer that intercepts and replays commentary, versus a full studio mockup, mirrors nock intercepting real network calls versus msw simulating requests at a higher level.

msw (Mock Service Worker) intercepts requests at the network layer using Node's http/https interceptors (or a real Service Worker in browsers), so your application code calls fetch/axios completely unmodified — unlike jest.mock('axios'), which replaces the module import itself.

Testing Error and Timeout Scenarios

A well-tested HTTP integration covers more than the happy path: axios.get.mockRejectedValueOnce(new Error('Network Error')) simulates a connection failure, resolving with { status: 500 } or { status: 404 } (ok: false for fetch) simulates server errors and missing resources, and with msw you can define a handler that returns ctx.status(500) or delays a response to simulate a timeout. Testing these paths verifies your error-handling code — retries, fallback UI, user-facing error messages — actually works rather than only being exercised by the successful case.

🏏

Cricket analogy: Forgetting to reset a scripted scoreboard after simulating a rain delay could leave a fake score displayed during the next real match, mirroring mocks leaking between tests.

If you use server.use() in msw to override a handler for one test, always call server.resetHandlers() in afterEach — otherwise that one-off override silently applies to every subsequent test in the file.

  • Mocking HTTP calls keeps tests fast, deterministic, and independent of real network availability or third-party API rate limits.
  • jest.mock('axios') combined with mockResolvedValue/mockRejectedValue is the simplest way to fake a specific library's request methods.
  • For native fetch, assigning global.fetch = jest.fn() lets you control resolved Response-like objects per test.
  • nock intercepts outgoing HTTP requests at Node's http/https module level, which works even for libraries you don't directly mock.
  • msw (Mock Service Worker) intercepts requests at the network boundary in both Node and the browser, so application code calling fetch/axios stays completely unmodified.
  • Simulating error and timeout scenarios (mockRejectedValue, 500 responses, network errors) is essential for testing an app's failure-handling paths, not just the happy path.
  • Always reset HTTP mocks/handlers between tests (afterEach) to prevent one test's stubbed response from silently affecting another.

Practice what you learned

Was this page helpful?

Topics covered

#Testing#JestStudyNotes#TestingQA#MockingHTTPRequests#Mocking#HTTP#Requests#Mock#Networking#StudyNotes#SkillVeris