Jest · Unit tests that survive refactors
What are manual mocks and when should you use them?
Short answer
A manual mock is a reusable fake stored in a __mocks__ directory next to the module or at the project root. Use it for a stable shared fake such as a client SDK; use an inline factory for one-off behaviour.
Manual mocks move a fake out of individual test files so several tests can share the same substitute. Jest looks for a __mocks__ folder adjacent to the module, and for node modules it also checks a root-level __mocks__ directory. User modules in __mocks__ still need a jest.mock call to opt in; some built-in node modules behave differently, so verify the behaviour for the version you use.
export const track = jest.fn();
export const identify = jest.fn();
jest.mock("./analytics");
import { track } from "./analytics";
test("tracks a signup", () => {
signup("asha@example.com");
expect(track).toHaveBeenCalledWith("signup");
});When a manual mock pays off
- The same fake is needed by many test files
- The real module is a third-party SDK with a large surface
- The fake should mirror the module's public API
- The behaviour is stable and does not change per test
The risk is drift. A manual mock can drift away from the real module and keep tests green while production breaks. Keep the mock small, update it when the interface changes, and add a type check that the fake still satisfies the module's exported shape where practical.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1Where does Jest look for a manual mock?
- 2Why does a manual mock need a jest.mock call?
- 3How do you keep a manual mock from drifting?
- 4When is dependency injection better than a module mock?
Say it in the interview
A manual mock is a reusable fake in a __mocks__ directory that replaces a module's exports. I use one when many files need the same fake for a stable interface, like a third-party analytics SDK. The tradeoff is drift, so I keep it small and type-checked where possible. For first-party code I usually prefer injecting the dependency, because it is easier to vary and the coupling is explicit.
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.