| name | cpp-mock-testing |
| description | Automates mock test creation for C++ projects using Google Mock (GMock) framework with consistent software testing patterns. Use when creating tests with mocked dependencies, interface mocking, behavior verification, or when the user mentions mocks, stubs, fakes, or GMock. |
| metadata | {"version":"1.1.0","activation":{"implicit":true,"priority":1,"triggers":["mock","gmock","stub","fake","mock object","test double","mocked dependency"],"match":{"languages":["cpp","c","c++"],"paths":["src/**/*_test.cpp","tests/**/*_test.cpp","test/**/*_test.cpp"],"prompt_regex":"(?i)(mock|gmock|stub|fake|test double|mocked|interface mock)"}},"usage":{"load_on_prompt":true,"autodispatch":true}} |
Mock Testing
Instructions for AI coding agents on automating mock test creation using Google Mock (GMock) with consistent software testing patterns in this C++ project.
1. Benefits
-
Isolation
Isolates the unit under test from external dependencies, ensuring tests focus on the specific component's behavior.
-
Control
Provides precise control over dependency behavior through expectations and return values, enabling thorough testing of edge cases and error conditions.
-
Verification
Automatically verifies that dependencies are called correctly with expected parameters and call counts.
-
Flexibility
Supports various testing scenarios including strict mocks, nice mocks, and sequence verification for complex interactions.
2. Patterns
-
Mock Objects
Simulated objects that mimic the behavior of real objects in controlled ways. They verify interactions between the unit under test and its dependencies.
-
Interface Mocking
Creating mock implementations of abstract interfaces or base classes to isolate the unit under test from concrete implementations.
-
Behavior Verification
Verifying that methods are called with expected arguments and in the correct order, rather than just checking return values.
-
Return Value Stubbing
Configuring mock objects to return specific values when their methods are called, allowing control over dependency behavior during tests.
-
Exception Injection
Using mocks to simulate error conditions by throwing exceptions, enabling tests to verify error handling logic.
3. Workflow
-
Identify Dependencies
Identify interfaces or classes that need to be mocked (e.g., database connections, file systems, network services, external APIs).
-
Create Mock Classes
Create mock classes for interfaces under test(s)/unit/<module>/ using GMock's MOCK_METHOD macro.
-
Register with CMake
Add the test file to test(s)/unit/<module>/CMakeLists.txt using meta_gtest() with WITH_GMOCK option.
meta_gtest(
WITH_GMOCK
TARGET ${PROJECT_NAME}-test
SOURCES
<header>_test.cpp
)
-
Define Expectations
Set up expectations using EXPECT_CALL to specify:
- Which methods should be called
- Expected arguments (using matchers)
- Call frequency (Times, AtLeast, AtMost, etc.)
- Return values or actions
-
Test Coverage Requirements
Include comprehensive scenarios:
- Normal operation with mocked dependencies
- Error conditions (exceptions, null returns, invalid data)
- Boundary conditions in dependency interactions
- Sequence of calls to multiple dependencies
- Concurrent access scenarios when applicable
-
Apply Templates
Structure all tests using the template pattern below.
4. Commands
| Command | Description |
|---|
make cmake-gcc-test-unit-build | CMake preset configuration with GMock support and Compile with Ninja |
make cmake-gcc-test-unit-run | Execute tests via ctest (mock tests are part of unit tests) |
make cmake-gcc-test-unit-coverage | Execute tests via ctest and generate coverage reports including mock test coverage |
5. Style Guide
6. Template
Use these templates for new mock tests. Replace placeholders with actual values.
6.1. File Header Template
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <memory>
#include <string>
#include <vector>
#include "<module>/<interface>.hpp"
#include "<module>/<implementation>.hpp"
using namespace <namespace>;
using namespace ::testing;
6.2. Mock Class Template
class Mock<Interface> : public <Interface>
{
public:
MOCK_METHOD(<return_type>, <method_name>, (<param_types>), (override));
MOCK_METHOD(<return_type>, <method_name2>, (<param_types>), (const, override));
};
6.3. Table-Driven Mock Test Template
TEST(<Module>Test, <FunctionName>WithMock)
{
struct Tests
{
std::string label;
struct In
{
} in;
struct Want
{
<output_type> expected;
<size_t> call_count;
<return_type> return_value;
<param_type> param;
} want;
};
const std::vector<Tests> tests = {
{
"case-description-1",
{},
{, 1, {}, {}}
},
{
"case-description-2",
{},
{, 1, {}, {}}
},
};
for (const auto &tc : tests)
{
SCOPED_TRACE(tc.label);
auto mock_dependency = std::make_shared<Mock<Interface>>();
EXPECT_CALL(*mock_dependency, <method_name>(tc.want.param))
.Times(tc.want.call_count)
.WillOnce(Return(tc.want.return_value));
<Implementation> object(mock_dependency);
auto got = object.<function>(tc.in.<input>);
EXPECT_EQ(got, tc.want.expected);
}
}
6.4. Sequence Verification Template
TEST(<Module>Test, <FunctionName>WithSequence)
{
auto mock_dependency = std::make_shared<StrictMock<Mock<Interface>>>();
InSequence seq;
EXPECT_CALL(*mock_dependency, <method1>(_)).WillOnce(Return(<value1>));
EXPECT_CALL(*mock_dependency, <method2>(_)).WillOnce(Return(<value2>));
<Implementation> object(mock_dependency);
auto got = object.<function>();
EXPECT_EQ(got, <expected>);
}
6.5. Exception Testing Template
TEST(<Module>Test, <FunctionName>ThrowsOnError)
{
auto mock_dependency = std::make_shared<Mock<Interface>>();
EXPECT_CALL(*mock_dependency, <method_name>(_))
.WillOnce(Throw(std::runtime_error("error message")));
<Implementation> object(mock_dependency);
EXPECT_THROW(object.<function>(), std::runtime_error);
}
6.6. NiceMock Template
TEST(<Module>Test, <FunctionName>WithNiceMock)
{
auto mock_dependency = std::make_shared<NiceMock<Mock<Interface>>>();
ON_CALL(*mock_dependency, <method_name>(_))
.WillByDefault(Return(<default_value>));
EXPECT_CALL(*mock_dependency, <critical_method>(_))
.Times(1)
.WillOnce(Return(<value>));
<Implementation> object(mock_dependency);
auto got = object.<function>();
EXPECT_EQ(got, <expected>);
}
7. References