如何用GTest/GMock验证类成员函数是否被调用(保留真实逻辑)
问题
生产环境中有简化后的MyClass类:
class MyClass{ public: MyClass(std::string input){/* 构造逻辑 */} void myFunc(){ // 真实业务逻辑 } };
另有otherCode.cpp中的代码会实例化该类并调用成员函数:
// otherCode.cpp 片段 auto myObj = MyClass("abc"); myObj.myFunc(); // 后续其他代码
现在需要在测试中确保myFunc()被执行,但不想MockMyClass或myFunc,要保留真实代码逻辑,仅验证myFunc()是否被调用,如何用GTest/GMock实现?
解决方案
方式一:自定义跟踪派生类(纯GTest实现)
创建一个继承自MyClass的测试类,在重写的myFunc里先调用基类的真实逻辑,再记录调用状态:
#include <gtest/gtest.h> class TrackedMyClass : public MyClass { public: using MyClass::MyClass; // 继承基类构造函数 static bool isMyFuncCalled; void myFunc() override { MyClass::myFunc(); // 执行真实逻辑 isMyFuncCalled = true; // 标记已调用 } }; // 初始化静态变量 bool TrackedMyClass::isMyFuncCalled = false; // 测试用例 TEST(MyClassTest, MyFuncIsCalled) { TrackedMyClass::isMyFuncCalled = false; // 替换原代码中的实例化,或通过依赖注入创建TrackedMyClass对象 auto myObj = TrackedMyClass("abc"); myObj.myFunc(); EXPECT_TRUE(TrackedMyClass::isMyFuncCalled); }
如果原代码是直接实例化MyClass,需要通过依赖注入修改原代码,让它接受MyClass的子类对象,测试时传入跟踪类实例即可。
方式二:使用GMock的部分Mock(更简洁)
GMock支持部分Mock,即只验证目标方法的调用情况,同时保留该方法的真实实现:
#include <gtest/gtest.h> #include <gmock/gmock.h> // 创建部分Mock类 class MockMyClass : public MyClass { public: using MyClass::MyClass; MOCK_METHOD(void, myFunc, (), (override)); // 定义默认动作:调用基类的真实myFunc void DefaultMyFunc() { MyClass::myFunc(); } }; TEST(MyClassTest, MyFuncIsCalled) { MockMyClass myObj("abc"); // 设置myFunc的默认行为是执行真实逻辑 ON_CALL(myObj, myFunc()).WillByDefault(::testing::Invoke(&myObj, &MockMyClass::DefaultMyFunc)); // 验证myFunc被调用至少一次 EXPECT_CALL(myObj, myFunc()).Times(::testing::AtLeast(1)); myObj.myFunc(); }
这种方式不需要额外的跟踪变量,直接用GMock的断言就能验证调用情况,同时完整保留原myFunc的逻辑。
注意:如果原代码无法修改实例化方式,可能需要调整代码结构(比如用工厂模式创建MyClass对象),让测试时可以替换为Mock类实例。
内容的提问来源于stack exchange,提问作者user1008636
相关产品推荐
相关产品推荐

