Introduction: why without mocks and fixtures tests are a lottery
\n\nImagine you are writing code for a spaceship. Your function calculates a trajectory by accessing the engine control module. How do you verify that the trajectory is correct without starting the actual engine? In the real world, this is a disaster. In the world of C++, this is a task for mock objects and fixtures.
\n\nIf you have ever written unit tests in C++, you have probably encountered problems: a test fails due to the network, database, or file system. Or you spend 10 lines preparing data for each check. Sound familiar? Then this article is for you.
\n\nWe will break down how mock objects in C++ help isolate code from the outside world, and fixtures help reuse test setup. No fluff, just code and practice. Let's go!
\n\nWhat are mock objects and why are they needed in C++
\n\nA mock object (or simply a mock) is a replacement for a real object that imitates its behavior. You tell the mock: "When the getData() method is called, return 42." And it obediently returns 42, without accessing the database, API, or file.
\n\nIn C++, mocks are especially important because the language does not forgive errors. If your class depends on the network, and the network goes down, the test will fail even though your code is perfect. Mocks solve this problem: they isolate the code under test.
\n\nMain use cases for mock objects in C++:
\n- \n
- External services (databases, REST APIs, files). \n
- Complex computations that slow down tests (cryptography, rendering). \n
- Non-deterministic functions (rand(), time()). \n
- Interaction verification: whether a method was called, how many times, with what arguments. \n
The de facto standard for creating mocks in C++ is the Google Mock library (also known as gmock), which comes bundled with Google Test. However, you can also write mocks manually — for small projects, this is even simpler.
\n\nFixtures: setting the stage for the test
\n\nA test fixture is a set of objects and data needed to run a test. Instead of writing this every time:
\n\nMyClass obj;\nobj.init("data");\nobj.connect();\n\n…you move this into a fixture. Google Test supports fixtures through inheritance from ::testing::Test. This is not just convenient — it is a best practice for C++ testing.
Fixtures solve three tasks:
\n- \n
- Code reuse — set it up once, use it in all tests. \n
- Test cleanliness — each test starts from the same state. \n
- Automatic cleanup — if resources need to be freed, this is done in the fixture's destructor. \n
Now let's combine mocks and fixtures in one example.
\n\nWriting a test with a mock object and a fixture: a real example
\n\nSuppose we have a class WeatherReporter that gets weather data via an API. We want to test the getTemperature() method without accessing the real server.
Step 1. Define the interface
\n\nTo plug in a mock, we need an abstract class. This is a key point: mocks work through polymorphism.
\n\n// weather_api.h\nclass WeatherAPI {\npublic:\n virtual ~WeatherAPI() = default;\n virtual double getTemperature(const std::string& city) = 0;\n virtual bool isAvailable() = 0;\n};\n\nStep 2. Implement the mock using Google Mock
\n\n// mock_weather_api.h\n#include <gmock/gmock.h>\n#include "weather_api.h"\n\nclass MockWeatherAPI : public WeatherAPI {\npublic:\n MOCK_METHOD(double, getTemperature, (const std::string& city), (override));\n MOCK_METHOD(bool, isAvailable, (), (override