Published on
· July 10, 2026

Mock Objects: what they are and how to use them in tests

Blog
  • Photo of Henrico Piubello
    Henrico Piubello
    Henrico Piubello
    IT Specialist - Grupo Voitto

    IT Specialist - Grupo Voitto

Metal gears representing mock objects isolating components in software unit tests

Mock objects are simulated objects that replace real dependencies — such as databases or APIs — during unit tests. They imitate the original component's behavior in a controlled way, letting you isolate the unit under test and verify its interactions without depending on external infrastructure.

What are mock objects?

Mock objects (or simply "mocks") are programmable substitutes for real objects, created specifically for software testing. A mock imitates the interface of a dependency — a repository, an HTTP client, a payment service — and responds to calls with values you define, as well as recording how it was invoked. This allows you to exercise a unit of code without triggering the real system behind it.

The term was coined in the paper "Endo-Testing: Unit Testing with Mock Objects", by Tim Mackinnon, Steve Freeman and Philip Craig, presented at the XP 2000 conference — the name is an allusion to Lewis Carroll's "Mock Turtle" character (read the original paper). The proposal was simple and powerful: instead of testing a class together with all its dependencies, you swap those dependencies for controlled doubles and observe the behavior from within.

In practice, the mock object serves two functions. First, it returns predictable data — always the same result, regardless of network, disk or time. Second, it acts as a spy: it knows whether the expected method was called, how many times and with which arguments. This combination makes mocks central pieces of a good set of software tests, especially in unit tests.

What is the difference between mock, stub, fake and spy?

A mock is only one of the types of "test double". The generic term was popularized by Gerard Meszaros and detailed by Martin Fowler in the article Mocks Aren't Stubs: the key distinction is that a stub uses state verification (you check the result), while a mock uses behavior verification (you check whether the expected interactions happened).

The table below summarizes the five most cited doubles:

TypeWhat it doesWhen to use
DummyFills parameters, never usedComplete method signatures
FakeReal but simplified implementationIn-memory database for tests
StubReturns fixed ready-made answersProvide input data
SpyStub that records callsAudit how it was invoked
MockVerifies expected interactionsValidate behavior and calls

In day-to-day conversation, many developers call any double a "mock", and libraries reinforce this. What matters is understanding the intent: if the test should confirm that a method was called with certain arguments, you want a mock; if it only needs a return value, a stub is enough.

Why use mock objects in unit tests?

Mock objects solve the central problem of unit testing: exercising a piece of code in isolation, without dragging the whole world along. By replacing heavy dependencies with controlled doubles, you gain fast, stable and easy-to-diagnose tests. The three benefits below appear in virtually every project that adopts the practice.

Component isolation

The mock ensures only the unit in focus is evaluated. If the test fails, the problem is in the tested code — not in an API (Application Programming Interface) that is down or a database with inconsistent data. This isolation brings the unit test closer to the idea of white-box testing, where you know and control the internal execution path.

Efficiency and speed

Real calls to databases, queues or web services cost milliseconds or seconds and can fail for external reasons. A mock returns the response instantly and always the same way, making the suite deterministic. This lets you run thousands of tests in seconds, something essential for continuous integration and fast feedback.

Simplified maintenance

As the software evolves, tests need to keep up. With mocks, changes to a dependency's behavior are reflected in a single configuration point of the test, with no need for full environments. This reduces the cost of keeping the suite alive and reliable over time.

How to create a mock object in practice?

Suppose a Pedido class depends on a BancoDeDados class to retrieve user information. Instead of accessing the real database, we create a mock object that simulates the buscar method, verify the result and keep the test fully isolated. See how this looks in the most popular tools.

Java with Mockito

Mockito is described in its official repository as the "most popular mocking framework for unit tests written in Java". It uses a fluent syntax with mock(), when() and thenReturn():

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;

class PedidoTest {
    @Test
    void calcularTotal_DeveRetornarTotalCorreto_QuandoUsuarioExiste() {
        // Configuração do mock
        BancoDeDados bancoMock = mock(BancoDeDados.class);
        when(bancoMock.buscar(anyInt())).thenReturn(new DadosUsuario(/* dados simulados */));

        // Execução
        Pedido pedido = new Pedido(bancoMock);
        double resultado = pedido.calcularTotalPedido(1);

        // Verificação de estado e de comportamento
        assertEquals(/* total esperado */, resultado);
        verify(bancoMock).buscar(1);
    }
}

Python with unittest.mock

Python ships the unittest.mock module in the standard library, with nothing to install. The Mock class creates configurable doubles via return_value, and assert_called_once_with verifies the interactions:

from unittest.mock import Mock

def test_calcular_total_pedido_quando_usuario_existe():
    # Configuração do mock
    banco_mock = Mock()
    banco_mock.buscar.return_value = DadosUsuario()  # dados simulados

    # Execução
    pedido = Pedido(banco_mock)
    resultado = pedido.calcular_total_pedido(1)

    # Verificação
    assert resultado == 42  # total esperado
    banco_mock.buscar.assert_called_once_with(1)

JavaScript with Jest

In the JavaScript ecosystem, Jest offers jest.fn() for mock functions and matchers like toHaveBeenCalledWith for behavior verification:

test('calcularTotalPedido retorna total correto quando usuário existe', () => {
  // Configuração do mock
  const bancoMock = { buscar: jest.fn(() => new DadosUsuario(/* dados simulados */)) };

  // Execução
  const pedido = new Pedido(bancoMock);
  const resultado = pedido.calcularTotalPedido(1);

  // Verificação
  expect(resultado).toBe(42); // total esperado
  expect(bancoMock.buscar).toHaveBeenCalledWith(1);
});

The pattern repeats in other languages: PHPUnit (createMock) in PHP, Moq (new Mock<T>()) in C#, Google Test/Google Mock (ON_CALL, EXPECT_CALL) in C++ and native libraries in Ruby (RSpec). The syntax changes, but the recipe is always the same: create the double, define the responses and verify the calls.

When to use and when to avoid mock objects?

Mock objects shine when the real dependency is slow, unstable, expensive or hard to prepare: databases, third-party APIs, payment gateways, email sending and system clocks. In these cases, the mock turns a fragile and slow test into a fast and repeatable one — exactly what you want in a large unit suite.

On the other hand, over-mocking is a known antipattern. By simulating simple objects you control yourself, the test starts to verify implementation details instead of observable behavior, and any legitimate refactor breaks dozens of tests. As a rule of thumb: prefer real objects when they are cheap, reserve mocks for the system's boundaries and complement with integration tests to validate the real communication.

It is also worth connecting mocks to your testing strategy as a whole. In approaches like behavior-driven development (BDD), doubles help specify expected interactions even before the implementation exists, keeping the focus on what the software should do. Here at CodeCrush we recommend treating the mock as a surgical tool, not as the default behavior of every test.

Conclusion

Mock objects are not a trick to "pass the test": they are a design instrument that forces you to think about the boundaries and dependencies of your code. Well used, they make the unit suite fast, deterministic and easy to diagnose; overused, they couple the tests to the implementation and become dead weight. A good developer knows the difference between mock, stub, fake and spy and applies each one with intention — mocking the external boundaries and trusting real objects and integration tests for the rest.

## faq

Frequently asked questions

What is a mock object in software testing?

A mock object is a programmable substitute for a real dependency, such as a database or an API. It returns predefined responses and records how it was called, allowing you to test a unit of code in isolation, quickly and predictably, without triggering external systems.

What is the difference between mock and stub?

A stub only provides ready-made answers so that the test can proceed, using state verification. A mock goes further: it verifies behavior, checking whether the expected methods were called with the correct arguments. According to Martin Fowler, this interaction verification is what defines a mock.

When should I use mock objects?

Use mocks when the real dependency is slow, unstable or hard to set up — databases, external APIs, email or payment services. They make unit tests fast and deterministic. Avoid mocking simple objects you control, as that couples the test to the implementation.

Do mock objects replace integration tests?

No. Mocks isolate units and verify internal logic, but they assume the simulated dependency behaves like the real one. Integration tests remain necessary to validate the real communication between components, databases and APIs. Mocks and integration tests are complementary, not substitutes.

Topics in this article

## continue lendo

Keep browsing

About the author

Photo of Henrico Piubello

Henrico Piubello

IT Specialist - Grupo Voitto · Grupo Voitto

See profile and all articles