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

Google Mock模板Mock类EXPECT_CALL报错及解决方案咨询

Google Mock调用Mock方法时出现"has no member named gmock_xxx"错误

我的代码背景

首先我定义了这样一个模板Mock类:

template<typename T> 
class ParseTreeMock : public ParseTreeInterface<T> { 
public: 
    MOCK_METHOD1(fillConfigTree, void(std::string const&)); 
    MOCK_METHOD1_T(getProperty, T(std::string const&)); 
    ParseTreeMock(): parseTree(std::make_unique<pt::ptree>()) { } 
    static std::unique_ptr<ParseTreeInterface<T>> getDefaultTree() { 
        return std::make_unique<ParseTreeMock<T>>(); 
    } 
private: 
    std::unique_ptr<pt::ptree> parseTree; 
}; 

然后在测试用例中创建Mock对象:

class ConfigTest : public ::testing::Test { 
protected: 
    std::unique_ptr<ParseTreeInterface<std::string>> treeMock; 
    virtual void SetUp() { 
        treeMock = ParseTreeMock<std::string>::getDefaultTree(); 
    } 
}; 

当我尝试为getProperty方法设置指定返回值时:

EXPECT_CALL(*treeMock, getProperty("miniReaderConfig.cacheConfig.cacheOnOff"))
    .willOnce(Return(false));

出现了编译错误:

In file included from ./lib/googletest/googlemock/include/gmock/gmock-generated-function-mockers.h:43:0,
                 from ./lib/googletest/googlemock/include/gmock/gmock.h:61,
                 from ./test/UT/Mocks/ParseTreeMock.hpp:2,
                 from test/UT/Configuration/ConfigTest.cpp:1:
test/UT/Configuration/ConfigTest.cpp: In member function ‘virtual void ConfigTest_CreateConfigurationWithoutErrors_Test::TestBody()’
./lib/googletest/googlemock/include/gmock/gmock-spec-builders.h:1844:12: error: ‘class miniReader::Configuration::ParseTreeInterface<std::__cxx11::basic_string<char> >’ has no member named ‘gmock_getProperty’
 did you mean ‘getProperty’
 ((obj).gmock_##call).InternalExpectedAt(__FILE__, __LINE__, #obj, #call)

错误原因分析

这个错误的核心是静态类型不匹配:

  • treeMock的静态类型是基类ParseTreeInterface<std::string>的智能指针,而Google Mock在生成Mock类时,会自动为每个MOCK_METHOD生成对应的gmock_xxx辅助成员函数(比如这里的gmock_getProperty),这些成员只存在于派生的ParseTreeMock类中,基类ParseTreeInterface里根本没有这些扩展方法。
  • 当你用*treeMock调用EXPECT_CALL时,编译器只能识别到基类的类型,自然找不到只有Mock子类才有的gmock_getProperty方法,于是抛出了这个错误。

解决方案

这里有两种可行的解决方法,你可以根据代码结构需求选择:

方法1:修改测试类中Mock对象的类型为Mock子类

把treeMock的类型从基类指针改成ParseTreeMock<std::string>的智能指针,让编译器直接看到Mock类的所有成员。修改后的测试类代码如下:

class ConfigTest : public ::testing::Test { 
protected: 
    // 改成Mock子类的智能指针
    std::unique_ptr<ParseTreeMock<std::string>> treeMock; 
    virtual void SetUp() { 
        // 因为getDefaultTree返回基类指针,需要做类型转换
        treeMock = std::static_pointer_cast<ParseTreeMock<std::string>>(
            ParseTreeMock<std::string>::getDefaultTree()
        );
        // 或者更简单:直接创建Mock对象,跳过getDefaultTree
        // treeMock = std::make_unique<ParseTreeMock<std::string>>();
    } 
}; 

如果可以的话,也可以修改getDefaultTree的返回类型为std::unique_ptr<ParseTreeMock<T>>,这样就不需要额外的类型转换了。

方法2:在EXPECT_CALL时显式转换为Mock子类指针

如果不想修改测试类中成员变量的类型,可以在设置期望的时候,把基类指针强制转换为Mock子类的指针:

EXPECT_CALL(*static_cast<ParseTreeMock<std::string>*>(treeMock.get()), 
            getProperty("miniReaderConfig.cacheConfig.cacheOnOff"))
    .willOnce(Return(false));

这种方法适合需要保持基类指针接口的场景,但每次设置期望都要做转换,相对麻烦一点。

内容的提问来源于stack exchange,提问作者Temple

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:30:52