Lesson 53 of 5822 min read

How to Mock Dependencies in NestJS Tests

Learn how to mock injected dependencies like repositories and services in NestJS tests using Jest mock functions and the overrideProvider API.

Author: CodersNexus

How to Mock Dependencies in NestJS Tests

The previous lesson tested UsersService in isolation, but it had no real dependencies of its own to worry about. Most real services, like the ones built throughout this course, depend on a database repository, an external API client, or another service. Mocking is how you replace these real dependencies with lightweight, controllable stand-ins specifically for testing, keeping unit tests fast and genuinely isolated.

NestJS Mock Dependencies Tests: Learning Objectives

  • Understand what a mock is and why real dependencies (like a database) shouldn't be used in unit tests.
  • Create a simple mock object using Jest's jest.fn() mock functions.
  • Provide a mock in a TestingModule using a custom provider with useValue.
  • Use overrideProvider() to replace a specific dependency after building the module.
  • Assert that a mocked method was called correctly using Jest's mock assertion methods.

NestJS Mock Dependencies Tests: Key Terms and Definitions

  • Mock: A fake, controllable replacement for a real dependency, used in tests to isolate the unit under test and avoid relying on real, potentially slow or unpredictable external systems.
  • jest.fn(): A Jest function that creates a mock function, which can be configured to return specific values and tracks how it was called.
  • useValue: A NestJS provider configuration option letting you supply a plain value (like a mock object) instead of a real class instance for a given injection token.
  • overrideProvider(): A method on a TestingModule builder used to explicitly replace a specific provider's implementation with a mock, after the module's base configuration is defined.
  • toHaveBeenCalledWith(): A Jest matcher used to assert that a mock function was called with specific arguments.

How NestJS Mock Dependencies Tests Works: Detailed Explanation

Consider UsersService from Module 3, which depends on an injected TypeORM Repository<User> to query and persist data. A true unit test for UsersService should verify its own logic, does it correctly call findOne() with the right ID, does it correctly throw NotFoundException when appropriate, without actually connecting to a real database. Doing so would make the test slow, dependent on external infrastructure being available, and would blur the line between testing UsersService's own logic and testing the database itself.

A mock solves this by providing a fake, minimal stand-in object implementing just enough of the real dependency's interface (like find(), findOne(), save()) to satisfy what the code under test actually calls, using Jest's jest.fn() to create individual mock functions. Each jest.fn() can be configured to return a specific value when called (using .mockReturnValue() or .mockResolvedValue() for promises), simulating exactly what the real dependency would return in a given test scenario, entirely under your control.

To actually supply this mock object in place of the real repository within a TestingModule, you use a custom provider configuration instead of just listing the class directly: { provide: getRepositoryToken(User), useValue: mockUserRepository }, where useValue tells NestJS's DI container to use this plain object directly whenever something requests that injection token, rather than trying to construct a real instance.

An alternative, sometimes more convenient approach is overrideProvider(), called on the TestingModule builder before .compile(): .overrideProvider(getRepositoryToken(User)).useValue(mockUserRepository). This lets you define the testing module's base configuration more naturally, then explicitly swap out a specific dependency's implementation, which can read slightly more clearly when a module has many providers and only one needs mocking.

Once a mock is in place and a test runs, Jest's mock functions automatically track how they were called, letting you make powerful assertions beyond just checking a return value: expect(mockUserRepository.findOne).toHaveBeenCalledWith({ where: { id: 1 } }) verifies not just that the service returned the right thing, but that it correctly called its dependency with the exact arguments you'd expect, giving you confidence in the internal correctness of the logic being tested, not just its final output.

Interview-Friendly Explanation

A strong interview or viva answer for nestjs mock dependencies tests must go beyond a one-line definition. Interviewers evaluating backend developers reward answers that combine a precise definition, a clear working explanation, a real-world example, and a conclusion that highlights why it matters for shipping reliable production Node.js applications. Use the four-point framework below when answering under time pressure.

  • Definition point: Mock: A fake, controllable replacement for a real dependency, used in tests to isolate the unit under test and avoid relying on real, potentially slow or unpredictable external systems.
  • Working point: Create a simple mock object using Jest's jest.fn() mock functions.
  • Example point: Mocking TypeORM repositories, Prisma clients, or Mongoose models exactly like this lesson's example is standard practice across virtually every well-tested NestJS codebase using a database.
  • Conclusion point: Mocking is what keeps unit tests fast, reliable, and genuinely focused on the unit under test's own logic.

How to Answer This in a Technical Interview

  1. Give a two-to-three sentence definition using correct testing terminology (unit, integration, e2e).
  2. Add one specific example drawn from a real backend scenario such as testing an auth flow or a CRUD API.
  3. Mention a relevant trade-off, such as speed versus realism, since interviewers often probe this contrast.
  4. Close with one benefit, limitation, or production consequence of getting this wrong.
  5. Avoid vague answers like "it just makes sure the code works" — interviewers filter these out immediately.

Practical Scenario

Imagine you are shipping frequent changes to a production backend for a SaaS product, similar to systems used at companies like Razorpay, Freshworks, or Zomato. Every lesson in this module maps directly to a decision you will make to ship confidently: what to test, how to isolate it, and how to know your test suite is actually catching real problems before they reach users.

NestJS Mock Dependencies Tests: Architecture and Flow Diagram

Visualize the mocking flow:

[Real Repository<User>] --replaced in tests by--> [mockUserRepository = { findOne: jest.fn(), save: jest.fn(), ... }]

[Test.createTestingModule({ providers: [UsersService, { provide: getRepositoryToken(User), useValue: mockUserRepository }] })] --> [UsersService receives the MOCK, not a real database connection] --> [Test configures mock return values and asserts on how the mock was called]

NestJS Mock Dependencies Tests: Technique Reference Table

TechniqueHow It WorksWhen to Use
useValue providerDirectly supplies a plain mock object for a given injection tokenStraightforward, defined upfront in the testing module's configuration
overrideProvider()Swaps a specific provider's implementation after the base module config is setWhen mocking just one or two dependencies out of a larger module setup
jest.fn().mockResolvedValue(x)Configures a mock function to return a resolved Promise of x when calledMocking async methods, like repository calls returning Promises
.toHaveBeenCalledWith(args)Asserts a mock function was called with specific argumentsVerifying the unit under test calls its dependencies correctly

NestJS Mock Dependencies Tests: NestJS Code Example

// users.service.spec.ts — mocking a TypeORM repository dependency
import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { NotFoundException } from '@nestjs/common';
import { UsersService } from './users.service';
import { User } from './user.entity';

describe('UsersService', () => {
  let service: UsersService;

  // A minimal mock implementing only the repository methods UsersService actually uses
  const mockUserRepository = {
    findOne: jest.fn(),
    save: jest.fn(),
    create: jest.fn(),
  };

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        UsersService,
        {
          provide: getRepositoryToken(User),
          useValue: mockUserRepository,
        },
      ],
    }).compile();

    service = module.get<UsersService>(UsersService);

    jest.clearAllMocks(); // reset call history between tests
  });

  it('should return a user when found', async () => {
    const fakeUser = { id: 1, name: 'Asha Mehta' };
    mockUserRepository.findOne.mockResolvedValue(fakeUser);

    const result = await service.findOne(1);

    expect(result).toEqual(fakeUser);
    expect(mockUserRepository.findOne).toHaveBeenCalledWith({ where: { id: 1 } });
  });

  it('should throw NotFoundException when user does not exist', async () => {
    mockUserRepository.findOne.mockResolvedValue(null);

    await expect(service.findOne(999)).rejects.toThrow(NotFoundException);
  });
});

mockUserRepository is a plain object implementing only findOne, save, and create as jest.fn() mock functions, deliberately minimal since UsersService (from Module 3) only calls these specific methods. This mock is supplied via the { provide: getRepositoryToken(User), useValue: mockUserRepository } custom provider, ensuring UsersService receives this fake object instead of a real TypeORM repository. The first test configures mockUserRepository.findOne.mockResolvedValue(fakeUser), simulating a successful database lookup, then asserts both that the service returned the expected user and, critically, that it called findOne() with exactly the right query shape. The second test configures the same mock to resolve to null, simulating a 'not found' scenario, and verifies the service correctly throws NotFoundException in response, exactly as it should per the logic first introduced in Module 3, all without ever touching a real database.

Real-World NestJS Mock Dependencies Tests Industry Examples

  • Mocking TypeORM repositories, Prisma clients, or Mongoose models exactly like this lesson's example is standard practice across virtually every well-tested NestJS codebase using a database.
  • External API integrations (payment gateways, email providers, third-party services) are almost always mocked in unit tests, since making real network calls during a test run would be slow, unreliable, and potentially costly.
  • Teams enforce a strict rule that unit tests must never touch a real database or external network call, reserving that kind of realistic interaction specifically for integration and e2e tests covered later in this module.
  • Complex business logic involving multiple conditional paths (like different responses based on a payment gateway's mocked success or failure) is often most thoroughly tested by configuring different mock return values across several distinct test cases.

NestJS Mock Dependencies Tests Interview Questions and Answers

Q1. What is a mock, and why is it used in unit tests instead of a real dependency like a database?

Short answer: A mock is a fake, controllable stand-in for a real dependency, implementing just enough of its interface to satisfy what the code under test actually calls. It's used instead of a real dependency, like a database, to keep unit tests fast, reliable, and genuinely isolated, testing only the unit's own logic rather than incidentally also testing the correctness or availability of an external system.

Detailed explanation: Consider UsersService from Module 3, which depends on an injected TypeORM Repository<User> to query and persist data. A true unit test for UsersService should verify its own logic, does it correctly call findOne() with the right ID, does it correctly throw NotFoundException when appropriate, without actually connecting to a real database. Doing so would make the test slow, dependent on external infrastructure being available, and would blur the line between testing UsersService's own logic and testing the database itself. A mock solves this by providing a fake, minimal stand-in object implementing just enough of the real dependency's interface (like find(), findOne(), save()) to satisfy what the code under test actually calls, using Jest's jest.fn() to create individual mock functions. Each jest.fn() can be configured to return a specific value when called (using .mockReturnValue() or .mockResolvedValue() for promises), simulating exactly what the real dependency would return in a given test scenario, entirely under your control. To actually supply this mock object in place of the real repository within a TestingModule, you use a custom provider configuration instead of just listing the class directly: { provide: getRepositoryToken(User), useValue: mockUserRepository }, where useValue tells NestJS's DI container to use this plain object directly whenever something requests that injection token, rather than trying to construct a real instance. An alternative, sometimes more convenient approach is overrideProvider(), called on the TestingModule builder before .compile(): .overrideProvider(getRepositoryToken(User)).useValue(mockUserRepository). This lets you define the testing module's base configuration more naturally, then explicitly swap out a specific dependency's implementation, which can read slightly more clearly when a module has many providers and only one needs mocking. Once a mock is in place and a test runs, Jest's mock functions automatically track how they were called, letting you make powerful assertions beyond just checking a return value: expect(mockUserRepository.findOne).toHaveBeenCalledWith({ where: { id: 1 } }) verifies not just that the service returned the right thing, but that it correctly called its dependency with the exact arguments you'd expect, giving you confidence in the internal correctness of the logic being tested, not just its final output.

Practical example: Mocking TypeORM repositories, Prisma clients, or Mongoose models exactly like this lesson's example is standard practice across virtually every well-tested NestJS codebase using a database.

Interview tip: Mocks replace real dependencies (databases, APIs) with fast, controllable fakes, keeping unit tests isolated and reliable.

Revision hook: Mocking is what keeps unit tests fast, reliable, and genuinely focused on the unit under test's own logic.

Q2. How would you mock a TypeORM repository dependency in a NestJS test?

Short answer: You create a plain object with jest.fn() mock functions for each repository method the service under test actually uses (like findOne, save), then supply this mock object in the testing module using a custom provider: { provide: getRepositoryToken(EntityName), useValue: mockObject }, ensuring the service receives this mock instead of a real repository instance.

Detailed explanation: mockUserRepository is a plain object implementing only findOne, save, and create as jest.fn() mock functions, deliberately minimal since UsersService (from Module 3) only calls these specific methods. This mock is supplied via the { provide: getRepositoryToken(User), useValue: mockUserRepository } custom provider, ensuring UsersService receives this fake object instead of a real TypeORM repository. The first test configures mockUserRepository.findOne.mockResolvedValue(fakeUser), simulating a successful database lookup, then asserts both that the service returned the expected user and, critically, that it called findOne() with exactly the right query shape. The second test configures the same mock to resolve to null, simulating a 'not found' scenario, and verifies the service correctly throws NotFoundException in response, exactly as it should per the logic first introduced in Module 3, all without ever touching a real database.

Practical example: External API integrations (payment gateways, email providers, third-party services) are almost always mocked in unit tests, since making real network calls during a test run would be slow, unreliable, and potentially costly.

Interview tip: jest.fn() creates mock functions; .mockReturnValue()/.mockResolvedValue() configure what they return when called.

Revision hook: A good mock implements only what the code under test actually calls, nothing more.

Q3. What is the purpose of Jest matchers like toHaveBeenCalledWith()?

Short answer: toHaveBeenCalledWith() asserts that a mock function was called with specific arguments, letting a test verify not just the final output of the unit under test, but also that it correctly interacts with its dependencies, such as calling a repository's findOne() method with the exact expected query conditions.

Detailed explanation: Mocking replaces a real, potentially slow or unpredictable dependency, like a TypeORM repository or an external API client, with a lightweight, fully controllable fake object built using Jest's jest.fn() mock functions, keeping unit tests fast and genuinely isolated to the logic of the unit under test. This mock is supplied within a TestingModule using a custom provider with useValue (or swapped in afterward using overrideProvider()), ensuring the service being tested receives the mock rather than attempting to construct a real dependency. Configuring a mock's return values with .mockReturnValue() or .mockResolvedValue() simulates specific test scenarios, such as a successful lookup or a 'not found' case, while Jest matchers like toHaveBeenCalledWith() let tests verify not just a method's final output but that it correctly interacted with its dependencies, providing genuine confidence in the internal correctness of the code being tested.

Practical example: Teams enforce a strict rule that unit tests must never touch a real database or external network call, reserving that kind of realistic interaction specifically for integration and e2e tests covered later in this module.

Interview tip: useValue (in providers) or overrideProvider() supplies a mock in place of a real dependency within a TestingModule.

Revision hook: Resetting mock state between tests (via jest.clearAllMocks() or a fresh beforeEach()) is essential for reliable, independent tests.

Q4. What is the difference between using a useValue provider and calling overrideProvider() to supply a mock?

Short answer: Both achieve the same end result, replacing a real dependency with a mock. useValue is specified directly within the initial Test.createTestingModule() configuration object. overrideProvider() is called as a separate, chained method on the module builder before .compile(), which can read more clearly when you want to define a module's broader configuration first and then explicitly call out which specific provider is being overridden with a mock.

Detailed explanation: Consider UsersService from Module 3, which depends on an injected TypeORM Repository<User> to query and persist data. A true unit test for UsersService should verify its own logic, does it correctly call findOne() with the right ID, does it correctly throw NotFoundException when appropriate, without actually connecting to a real database. Doing so would make the test slow, dependent on external infrastructure being available, and would blur the line between testing UsersService's own logic and testing the database itself. A mock solves this by providing a fake, minimal stand-in object implementing just enough of the real dependency's interface (like find(), findOne(), save()) to satisfy what the code under test actually calls, using Jest's jest.fn() to create individual mock functions. Each jest.fn() can be configured to return a specific value when called (using .mockReturnValue() or .mockResolvedValue() for promises), simulating exactly what the real dependency would return in a given test scenario, entirely under your control. To actually supply this mock object in place of the real repository within a TestingModule, you use a custom provider configuration instead of just listing the class directly: { provide: getRepositoryToken(User), useValue: mockUserRepository }, where useValue tells NestJS's DI container to use this plain object directly whenever something requests that injection token, rather than trying to construct a real instance. An alternative, sometimes more convenient approach is overrideProvider(), called on the TestingModule builder before .compile(): .overrideProvider(getRepositoryToken(User)).useValue(mockUserRepository). This lets you define the testing module's base configuration more naturally, then explicitly swap out a specific dependency's implementation, which can read slightly more clearly when a module has many providers and only one needs mocking. Once a mock is in place and a test runs, Jest's mock functions automatically track how they were called, letting you make powerful assertions beyond just checking a return value: expect(mockUserRepository.findOne).toHaveBeenCalledWith({ where: { id: 1 } }) verifies not just that the service returned the right thing, but that it correctly called its dependency with the exact arguments you'd expect, giving you confidence in the internal correctness of the logic being tested, not just its final output.

Practical example: Complex business logic involving multiple conditional paths (like different responses based on a payment gateway's mocked success or failure) is often most thoroughly tested by configuring different mock return values across several distinct test cases.

Interview tip: toHaveBeenCalledWith() and similar matchers verify a mock was called correctly, not just that the final result was right.

Revision hook: Asserting on how a mock was called, not just what a method returned, verifies internal correctness, not just final output.

NestJS Mock Dependencies Tests MCQs and Practice Questions

1. What Jest function is used to create a mock function?

  1. jest.mock()
  2. jest.fn()
  3. jest.spy()
  4. jest.stub()

Answer: B. jest.fn()

Explanation: jest.fn() creates a mock function that can be configured with specific return values and automatically tracks how it was called, forming the building block of most mocks in Jest tests.

Concept link: Mocks replace real dependencies (databases, APIs) with fast, controllable fakes, keeping unit tests isolated and reliable.

Why this matters: Mocking is what keeps unit tests fast, reliable, and genuinely focused on the unit under test's own logic.

2. Which provider configuration option supplies a plain mock object for a given injection token in a TestingModule?

  1. useClass
  2. useFactory
  3. useValue
  4. useExisting

Answer: C. useValue

Explanation: useValue directly supplies a specific value, such as a plain mock object, for a given injection token, telling NestJS's DI container to use exactly that value rather than constructing a real instance.

Concept link: jest.fn() creates mock functions; .mockReturnValue()/.mockResolvedValue() configure what they return when called.

Why this matters: A good mock implements only what the code under test actually calls, nothing more.

3. What does mockUserRepository.findOne.mockResolvedValue(fakeUser) configure?

  1. The real database to return fakeUser
  2. The mock findOne function to return a resolved Promise containing fakeUser when called
  3. A new database table
  4. An HTTP response

Answer: B. The mock findOne function to return a resolved Promise containing fakeUser when called

Explanation: mockResolvedValue() configures a Jest mock function to return a Promise that resolves to the given value, simulating what an async method like a repository's findOne() would return in a specific test scenario.

Concept link: useValue (in providers) or overrideProvider() supplies a mock in place of a real dependency within a TestingModule.

Why this matters: Resetting mock state between tests (via jest.clearAllMocks() or a fresh beforeEach()) is essential for reliable, independent tests.

4. Which Jest matcher would you use to verify a mock function was called with specific arguments?

  1. toBeDefined()
  2. toHaveBeenCalledWith()
  3. toThrow()
  4. toEqual()

Answer: B. toHaveBeenCalledWith()

Explanation: toHaveBeenCalledWith(expectedArgs) checks that a mock function was invoked with exactly the specified arguments, allowing tests to verify correct interaction with a dependency, not just the final result.

Concept link: toHaveBeenCalledWith() and similar matchers verify a mock was called correctly, not just that the final result was right.

Why this matters: Asserting on how a mock was called, not just what a method returned, verifies internal correctness, not just final output.

Common NestJS Mock Dependencies Tests Mistakes to Avoid

  • Creating an overly complete, complex mock replicating far more of a real dependency's behavior than the unit under test actually needs.
  • Forgetting to reset mock call history (using jest.clearAllMocks() or similar) between tests, causing assertions in one test to be affected by calls made in a previous test.
  • Mocking a dependency's return value incorrectly, such as using mockReturnValue() for a method that actually returns a Promise, when mockResolvedValue() is needed instead.
  • Testing the mock's own configured behavior rather than the actual logic of the service under test, losing sight of what the test is genuinely meant to verify.

NestJS Mock Dependencies Tests: Interview Notes and Exam Tips

  • Mocks replace real dependencies (databases, APIs) with fast, controllable fakes, keeping unit tests isolated and reliable.
  • jest.fn() creates mock functions; .mockReturnValue()/.mockResolvedValue() configure what they return when called.
  • useValue (in providers) or overrideProvider() supplies a mock in place of a real dependency within a TestingModule.
  • toHaveBeenCalledWith() and similar matchers verify a mock was called correctly, not just that the final result was right.

Key NestJS Mock Dependencies Tests Takeaways

  • Mocking is what keeps unit tests fast, reliable, and genuinely focused on the unit under test's own logic.
  • A good mock implements only what the code under test actually calls, nothing more.
  • Resetting mock state between tests (via jest.clearAllMocks() or a fresh beforeEach()) is essential for reliable, independent tests.
  • Asserting on how a mock was called, not just what a method returned, verifies internal correctness, not just final output.

NestJS Mock Dependencies Tests: Summary

Mocking replaces a real, potentially slow or unpredictable dependency, like a TypeORM repository or an external API client, with a lightweight, fully controllable fake object built using Jest's jest.fn() mock functions, keeping unit tests fast and genuinely isolated to the logic of the unit under test. This mock is supplied within a TestingModule using a custom provider with useValue (or swapped in afterward using overrideProvider()), ensuring the service being tested receives the mock rather than attempting to construct a real dependency. Configuring a mock's return values with .mockReturnValue() or .mockResolvedValue() simulates specific test scenarios, such as a successful lookup or a 'not found' case, while Jest matchers like toHaveBeenCalledWith() let tests verify not just a method's final output but that it correctly interacted with its dependencies, providing genuine confidence in the internal correctness of the code being tested.

Frequently Asked Questions

No, a good mock only needs to implement the specific methods the unit under test actually calls; including unused methods adds unnecessary maintenance overhead without providing any additional testing value. In interviews, tie this back to: Mocks replace real dependencies (databases, APIs) with fast, controllable fakes, keeping unit tests isolated and reliable. In real applications, consider this example: Mocking TypeORM repositories, Prisma clients, or Mongoose models exactly like this lesson's example is standard practice across virtually every well-tested NestJS codebase using a database. Key revision takeaway: Mocking is what keeps unit tests fast, reliable, and genuinely focused on the unit under test's own logic.

mockReturnValue(x) configures a mock function to return x directly and synchronously when called. mockResolvedValue(x) is specifically for mocking asynchronous functions, configuring the mock to return a Promise that resolves to x, matching how real async methods like repository calls actually behave. In interviews, tie this back to: jest.fn() creates mock functions; .mockReturnValue()/.mockResolvedValue() configure what they return when called. In real applications, consider this example: External API integrations (payment gateways, email providers, third-party services) are almost always mocked in unit tests, since making real network calls during a test run would be slow, unreliable, and potentially costly. Key revision takeaway: A good mock implements only what the code under test actually calls, nothing more.

Without clearing mock call history between tests, assertions like toHaveBeenCalledWith() in a later test could be affected by calls made to the same mock function during an earlier test, potentially causing confusing false positives or false negatives in your assertions. In interviews, tie this back to: useValue (in providers) or overrideProvider() supplies a mock in place of a real dependency within a TestingModule. In real applications, consider this example: Teams enforce a strict rule that unit tests must never touch a real database or external network call, reserving that kind of realistic interaction specifically for integration and e2e tests covered later in this module. Key revision takeaway: Resetting mock state between tests (via jest.clearAllMocks() or a fresh beforeEach()) is essential for reliable, independent tests.

Yes, the exact same approach applies to mocking any injected dependency, whether it's a TypeORM repository, another NestJS service, an external API client wrapper, or any other provider, since NestJS's dependency injection doesn't distinguish between these when supplying a useValue mock. In interviews, tie this back to: toHaveBeenCalledWith() and similar matchers verify a mock was called correctly, not just that the final result was right. In real applications, consider this example: Complex business logic involving multiple conditional paths (like different responses based on a payment gateway's mocked success or failure) is often most thoroughly tested by configuring different mock return values across several distinct test cases. Key revision takeaway: Asserting on how a mock was called, not just what a method returned, verifies internal correctness, not just final output.

Functionally, they achieve the same result, replacing a provider with a mock value. The choice is mostly stylistic; overrideProvider() can make it visually clearer in test code that a specific, otherwise-real provider is being deliberately swapped for a mock. In interviews, tie this back to: Mocks replace real dependencies (databases, APIs) with fast, controllable fakes, keeping unit tests isolated and reliable. In real applications, consider this example: Mocking TypeORM repositories, Prisma clients, or Mongoose models exactly like this lesson's example is standard practice across virtually every well-tested NestJS codebase using a database. Key revision takeaway: Mocking is what keeps unit tests fast, reliable, and genuinely focused on the unit under test's own logic.

A mock's data only needs to be detailed enough to satisfy whatever the test actually checks; overly elaborate, unrealistic, or unnecessarily detailed fake data adds maintenance burden without improving the test's ability to catch real bugs in the logic being verified. In interviews, tie this back to: jest.fn() creates mock functions; .mockReturnValue()/.mockResolvedValue() configure what they return when called. In real applications, consider this example: External API integrations (payment gateways, email providers, third-party services) are almost always mocked in unit tests, since making real network calls during a test run would be slow, unreliable, and potentially costly. Key revision takeaway: A good mock implements only what the code under test actually calls, nothing more.