gMock向上转型(Upcasting)时EXPECT_CALL失效问题求助
解决gMock向上转型后无法捕获方法调用的问题
这个问题我之前踩过一模一样的坑,核心原因其实很简单——你的基类MyClass里的call方法不是虚函数!
为什么会出现这个问题?
C++里非虚函数的调用是静态绑定的:编译阶段就已经确定了要调用的函数版本。当你把MockMyClass对象向上转型为MyClass&或MyClass*后,调用call时,编译器会直接调用基类MyClass的原生方法,完全不会走到你在MockMyClass中定义的mock实现里,gMock自然就捕获不到这个调用了。
解决方案:给基类方法加上virtual关键字
只需要修改基类,把call声明为虚函数,让C++启用动态绑定,这样运行时就会根据对象的实际类型调用对应的方法(也就是mock的版本)。
修正后的完整代码示例:
#include "gtest/gtest.h" #include "gmock/gmock.h" using namespace testing; using namespace std; class MyClass { public: MyClass(int xxx) {} // 关键:将call声明为虚函数,这里用纯虚强制子类实现(如果基类不需要默认逻辑) virtual int call(int x) = 0; // 如果基类需要默认业务逻辑,可以写成:virtual int call(int x) { return 0; }; }; class MockMyClass : public MyClass { public: MockMyClass(int xxx) : MyClass(xxx) {}; // gMock的MOCK_METHOD会自动生成虚函数的重写版本,无需额外处理 MOCK_METHOD1(call, int(int)); }; TEST(TestMyClass, worksFine) { MockMyClass mock(111); EXPECT_CALL(mock, call(_)) .WillOnce(Return(2000)); mock.call(23); // 直接调用mock对象,正常捕获 } TEST(TestMyClass, nowWorks) { MockMyClass mock(111); MyClass &myClassNotMock = mock; EXPECT_CALL(mock, call(_)) .WillOnce(Return(2000)); myClassNotMock.call(23); // 向上转型后调用,现在能被gMock正常捕获了 }
额外注意事项
- 如果基类的
call方法有自己的业务实现,不用改成纯虚函数,只要保留virtual关键字即可,mock类的MOCK_METHOD会自动覆盖这个虚函数。 - 指针转型的场景和引用完全一致,只要基类方法是虚的,
MyClass* ptr = &mock; ptr->call(23);也能被gMock正常捕获。
内容的提问来源于stack exchange,提问作者Mike Kuasinski
相关产品推荐
相关产品推荐

