Mocking Styles in Testing: Narrow vs Broad

December 12, 2025

Summary

Introduction


Mocking is one of those testing topics that looks easy at first, until your test suite starts breaking for the wrong reasons, becomes hard to read, or ends up glued to implementation details. The Narrow vs Broad mocking discussion helps teams step back and think about how much they should mock and what their tests are really proving.

This post breaks down both approaches.

What Is Mocking and Why It Matters


Mocking is the practice of replacing real dependencies (databases, APIs, services) with controlled test doubles.

The goal is to:

  • Isolate behavior
  • Make tests faster
  • Mitigate risks caused by unreliable external systems

But how strict your mocks are defines whether you’re using a Narrow or Broad approach.

Think of it like checking a restaurant:

  • Do you verify each ingredient in the recipe?
  • Or just confirm the meal tastes right?

Narrow Mocks Explained


Narrow mocks focus on very specific interactions.

They verify:

  • Exact method calls
  • Call order
  • Arguments passed
  • Number of invocations

Example (JavaScript / Jest)

expect(paymentGateway.charge).toHaveBeenCalledWith(
  user.id,
  100,
  'USD'
);

Here, the test asserts how the system behaves internally and not just focus on the result.

When Narrow mocks shine

  • Critical business logic
  • Financial or compliance-sensitive flows
  • APIs with strict contracts

Broad Mocks Explained


Broad mocks focus on outcomes, not interactions.

They care about:

  • Returned values
  • State changes
  • Observable behavior

How the internals achieve the result is less important.

Example

const result = checkoutService.checkout(user);
expect(result.status).toBe('SUCCESS');

No concern about which methods were called, only what happened.

When Broad mocks shine

  • Refactoring-heavy codebases
  • High-level business scenarios
  • Tests meant to document behavior

Rule of thumb: The closer the test is to business value, the broader it should be.

Pros and Cons


Narrow Mocks

Pros

  • Precise validation
  • Early detection of contract changes
  • High confidence in interactions

Cons

  • Fragile tests
  • High maintenance cost
  • Discourages refactoring

Broad Mocks

Pros

  • Resilient to refactoring
  • Tests read like documentation
  • Faster to maintain

Cons

  • Less precise
  • Interaction bugs may slip through
  • Lower confidence in side effects

Concepts That Go in the Opposite Direction


If mocking itself becomes the problem, these approaches intentionally move away from heavy mocking:

1. Fake Implementations

Use simple, in-memory, or lightweight real implementations instead of mocks.

2. Integration Tests

Verify that real components work together (database, API, cache), rather than isolating everything.

3. Contract Testing

Validate agreements between services without mocking internal behavior.

4. Property-Based Testing

Validate system invariants and business rules, instead of testing specific call sequences or interactions.

Each of these reduces reliance on mocks and shifts confidence toward actual system behavior.

Conclusion


  • Use Nero mocks when correctness of interaction is critical.
  • Use Broad mocks when behavior and flexibility matter more.

Strong tests can combine both strategies intentionally.

Further Reading