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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 13:43:14