Loading...
Loading...
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.
npx skill4agent add sentenz/skills cpp-mock-testingIsolates the unit under test from external dependencies, ensuring tests focus on the specific component's behavior.
Provides precise control over dependency behavior through expectations and return values, enabling thorough testing of edge cases and error conditions.
Automatically verifies that dependencies are called correctly with expected parameters and call counts.
Supports various testing scenarios including strict mocks, nice mocks, and sequence verification for complex interactions.
Simulated objects that mimic the behavior of real objects in controlled ways. They verify interactions between the unit under test and its dependencies.
Creating mock implementations of abstract interfaces or base classes to isolate the unit under test from concrete implementations.
Verifying that methods are called with expected arguments and in the correct order, rather than just checking return values.
Configuring mock objects to return specific values when their methods are called, allowing control over dependency behavior during tests.
Using mocks to simulate error conditions by throwing exceptions, enabling tests to verify error handling logic.
test(s)/unit/<module>/MOCK_METHODtest(s)/unit/<module>/CMakeLists.txtmeta_gtest()WITH_GMOCKmeta_gtest(
WITH_GMOCK
TARGET ${PROJECT_NAME}-test
SOURCES
<header>_test.cpp
)EXPECT_CALL| Command | Description |
|---|---|
| CMake preset configuration with GMock support and Compile with Ninja |
| Execute tests via ctest (mock tests are part of unit tests) |
| Execute tests via ctest and generate coverage reports including mock test coverage |
Define mock classes inheriting from the interface to be mocked. Usemacro with proper method signature, including const qualifiers and override specifiers.MOCK_METHOD
GMock/GTest headers are listed first in mock test files as a convention to clearly identify the file as a test file using the GMock framework.
<gmock/gmock.h><gtest/gtest.h><memory><string>Useandusing namespace <namespace>;for convenience within test functions to access GMock matchers and actions.using namespace ::testing;
Use table-driven testing for multiple scenarios with the same mock setup. EachorTESTshould focus on one aspect of the interaction with mocked dependencies.TEST_F
Ignores unexpected calls (use for non-critical dependencies)
Fails on any unexpected calls (use for strict verification)
Warns on unexpected calls (balanced approach)
EXPECT_CALL.With().WillOnce().WillRepeatedly().Times()Eq()Gt()__Eq()Ne()Lt()Gt()Le()Ge()IsNull()NotNull()IsEmpty()SizeIs()Contains()ElementsAre()StartsWith()EndsWith()HasSubstr()MatchesRegex()Return()ReturnRef()Throw()DoAll()Invoke()UseorInSequenceobjects when call order matters.Sequence
Employfor traceable failures in table-driven mock tests.SCOPED_TRACE(tc.label)
Usemacros to allow all test cases to run. Mock expectations are automatically verified at the end of each test.EXPECT_*
#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;/**
* @brief Mock implementation of <Interface> for testing.
*/
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));
};TEST(<Module>Test, <FunctionName>WithMock)
{
// In-Got-Want
struct Tests
{
std::string label;
struct In
{
/* input types and names */
} in;
struct Want
{
<output_type> expected; // expected output type(s) and name(s)
/* expected mock call parameters and behavior */
<size_t> call_count; // number of times method should be called
<return_type> return_value; // value mock should return
<param_type> param; // expected parameter value(s)
} want;
};
// Table-Driven Testing
const std::vector<Tests> tests = {
{
"case-description-1",
/* in */ {/* input values */},
/* want */ {/* expected */, /* call_count */ 1, /* return_value */ {}, /* param */ {}}
},
{
"case-description-2",
/* in */ {/* input values */},
/* want */ {/* expected */, /* call_count */ 1, /* return_value */ {}, /* param */ {}}
},
// add more cases as needed
};
for (const auto &tc : tests)
{
SCOPED_TRACE(tc.label);
// Arrange
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);
// Act
auto got = object.<function>(tc.in.<input>);
// Assert
EXPECT_EQ(got, tc.want.expected);
}
}TEST(<Module>Test, <FunctionName>WithSequence)
{
// Arrange
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);
// Act
auto got = object.<function>();
// Assert
EXPECT_EQ(got, <expected>);
}TEST(<Module>Test, <FunctionName>ThrowsOnError)
{
// Arrange
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);
// Act & Assert
EXPECT_THROW(object.<function>(), std::runtime_error);
}TEST(<Module>Test, <FunctionName>WithNiceMock)
{
// Arrange
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);
// Act
auto got = object.<function>();
// Assert
EXPECT_EQ(got, <expected>);
}