Jest · Unit tests that survive refactors
How should you mock network requests in tests?
Short answer
Mock at the network boundary, not inside the component. Stub fetch or use MSW so the real request logic, parsing and error handling still execute.
A network mock should answer the question the code asks, such as a URL and method, and return a realistic response. That keeps serialization, status handling and retries under test. Mocking a data module instead skips all of that and can hide bugs in the layer you most need to verify.
beforeEach(() => {
globalThis.fetch = jest.fn().mockResolvedValue({
ok: true,
status: 200,
json: async () => ({ id: "u1", name: "Asha" }),
} as Response);
});
test("loads the profile", async () => {
await expect(loadProfile("u1")).resolves.toEqual({ id: "u1", name: "Asha" });
});Levels of network mocking
- Stub
fetchor an HTTP client for a small unit test - Use MSW for integration tests that need routing and realistic responses
- Use a contract test or a test server when the real transport matters
- Avoid mocking the component's data hook, because it skips the integration point
The response object needs the fields the code reads. A stub with only json will break code that checks ok or status. For error paths, return a non-2xx status and assert that the UI shows the error state, not just that the promise rejected.
fetch after the test. A global stub that leaks changes every later test and is a frequent cause of order-dependent failures.Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1Why is mocking a data hook worse than mocking fetch?
- 2What does a minimal fetch stub need to include?
- 3How do you test the error path of a request?
- 4When is MSW a better fit than a fetch stub?
Say it in the interview
I mock the transport so the request-building and response-parsing code still runs. For a small unit test a fetch stub is enough, as long as it includes the fields the code reads. For integration tests I prefer MSW because it routes by URL and method. I always restore the global afterward, and I test the error path with a non-2xx response.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Jest mock interview and get scored feedback on depth, clarity and confidence.