GMock中EXPECT_CALL匹配char*参数时因比较地址而非值导致断言失败,求解决方法
解决GMock中EXPECT_CALL比较char数组地址而非内容的问题
你说得完全对,GMock默认对const char*类型的参数是直接比较内存地址的,而不是字符串的实际内容——这就是为啥两个看起来一模一样的"hello_world",因为存在不同的内存位置,导致断言失败。另外还有一个容易被忽略的坑:你的Base类里的sendString方法不是虚函数,这会导致Mock对象的方法根本不会被调用!
下面是完整的解决步骤:
1. 将Base类的sendString改为虚函数
Mock机制依赖C++的动态多态,所以必须把要Mock的方法声明为虚函数,这样当通过基类指针调用时,才会触发到Mock类的实现:
// Base.h class Base { private: static Base* _ptrInstance; public: static Base* getInstance(); // 添加virtual关键字,让方法可被重写 virtual void sendString(const char* text, int value); };
2. 正确定义Mock类
确保你的Mock类继承自Base,并正确声明Mock方法:
#include <gmock/gmock.h> class BaseMock : public Base { public: MOCK_METHOD2(sendString, void(const char* text, int value)); };
3. 替换单例实例为Mock对象
因为你的Test函数调用的是Base::getInstance()获取的单例,所以必须在测试用例的初始化阶段,把单例的实例替换成Mock对象:
class myTest : public ::testing::Test { protected: BaseMock* mockBase; void SetUp() override { // 创建Mock实例并替换单例 mockBase = new BaseMock(); Base::_ptrInstance = mockBase; } void TearDown() override { // 测试结束后清理资源 delete mockBase; Base::_ptrInstance = nullptr; } };
4. 使用StrEq匹配器比较字符串内容
在EXPECT_CALL中,用GMock提供的StrEq匹配器代替直接传字符串字面量,它会比较两个C风格字符串的实际内容,而不是地址:
TEST_F(myTest, sendStringTest){ EXPECT_CALL(*mockBase, sendString(StrEq("hello_world"), 0)); Test(); }
如果需要忽略大小写的字符串比较,可以用CaseInsensitiveStrEq匹配器,用法和StrEq一致。
这样修改后,测试就能正确验证sendString是否被传入了内容为"hello_world"的字符串,而不会再因为内存地址不同而断言失败。
内容的提问来源于stack exchange,提问作者Huy Quang
相关产品推荐
相关产品推荐

