0Pricing
Node.js Backend Development Bootcamp · Lesson

Mocking & Test Doubles in Node.js

Learn how to isolate the code under test by replacing real dependencies with mocks, stubs, and spies so your unit tests stay fast and deterministic.

Mocking & Test Doubles in Node.js is a free Node.js Backend Development Bootcamp lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Node.js Backend Development Bootcamp learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

The Problem with Real Dependencies

A unit test should check one piece of logic in isolation. But real code calls databases, APIs, the clock, and the file system — all slow, flaky, and unpredictable.

Test doubles replace those dependencies with controllable fakes.

Types of Test Doubles

Common terms you will hear:

  • Stub: returns a canned value
  • Spy: records how it was called
  • Mock: a stub + spy with built-in expectations
  • Fake: a lightweight working implementation

Creating a Mock Function

In Jest, jest.fn() creates a mock function. It records every call and lets you assert on them later.

const callback = jest.fn();
callback('hello');
expect(callback).toHaveBeenCalledWith('hello');

Defining Return Values

Tell a mock what to return with mockReturnValue, or for async code use mockResolvedValue to resolve a promise.

const getUser = jest.fn().mockResolvedValue({ id: 1, name: 'Ada' });
const user = await getUser();
expect(user.name).toBe('Ada');

Asserting on Calls

Spies let you verify interactions:

  • toHaveBeenCalled()
  • toHaveBeenCalledTimes(n)
  • toHaveBeenCalledWith(args)
const save = jest.fn();
save({ id: 1 });
expect(save).toHaveBeenCalledTimes(1);

Mocking a Module

To replace an entire imported module, use jest.mock(). Every export becomes an auto-mock you can configure per test.

jest.mock('./mailer');
const mailer = require('./mailer');
mailer.send.mockResolvedValue(true);

Spying on Existing Methods

Sometimes you want to watch a real method without replacing it. jest.spyOn() wraps an existing method so you can assert and optionally override it.

const spy = jest.spyOn(console, 'log');
console.log('hi');
expect(spy).toHaveBeenCalledWith('hi');

Resetting Between Tests

Mocks accumulate state. Reset them between tests so calls from one test do not leak into another.

  • mockClear() clears call data
  • mockReset() also clears implementations
afterEach(() => {
  jest.clearAllMocks();
});

Mocking Time

Tests that depend on the current time are flaky. Jest fake timers let you control the clock so timeouts and dates are deterministic.

jest.useFakeTimers();
const fn = jest.fn();
setTimeout(fn, 1000);
jest.advanceTimersByTime(1000);
expect(fn).toHaveBeenCalled();

Dependency Injection Makes Mocking Easy

Code that receives its dependencies as arguments is far easier to test than code that imports them directly. Design for testability.

function createService(db) {
  return { getUser: id => db.find(id) };
}
const fakeDb = { find: jest.fn().mockReturnValue({ id: 1 }) };
const svc = createService(fakeDb);

Don't Over-Mock

Mocking too much produces tests that only confirm your mocks were called — not that the code works. Mock external boundaries (DB, network), but test real logic directly when you can.

Quick Check

Test your understanding of test doubles.

Recap

You learned to isolate code with test doubles:

  • Create mocks with jest.fn() and configure return values
  • Replace modules with jest.mock()
  • Watch real methods with jest.spyOn()
  • Reset mocks between tests and control time with fake timers
  • Inject dependencies for testability and avoid over-mocking

Good mocking keeps unit tests fast, reliable, and focused.

Frequently asked questions

Is the “Mocking & Test Doubles in Node.js” lesson free?

Yes — the full text of “Mocking & Test Doubles in Node.js” is free to read here on the web, and the Node.js Backend Development Bootcamp course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Node.js Backend Development Bootcamp course, upgrade to CoddyKit PRO.

What will I learn in “Mocking & Test Doubles in Node.js”?

Learn how to isolate the code under test by replacing real dependencies with mocks, stubs, and spies so your unit tests stay fast and deterministic. You practise Node.js Backend Development Bootcamp with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Node.js Backend Development Bootcamp?

No prior experience is required. Node.js Backend Development Bootcamp on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Mocking & Test Doubles in Node.js” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Node.js Backend Development Bootcamp lesson?

Yes. Every Node.js Backend Development Bootcamp lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Unit Testing with Jest
  2. Integration Testing API Endpoints
  3. Effective Debugging Techniques
  4. Mocking & Test Doubles in Node.js
← Back to Node.js Backend Development Bootcamp