You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:57:03