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

Google Test中调用mock shared_ptr方法触发段错误的问题

问题原因分析
  • ON_CALL匹配条件不匹配:最常见的根源是CoreBuilder的createWindow方法签名(比如参数类型/数量、是否为const成员函数)与GMock配置的期望不匹配,导致GMock没有触发预设的返回逻辑,最终返回shared_ptr的默认空值。
  • CoreBuilder传递方式错误:如果Engine构造函数接收的是CoreBuilder的值传递,会导致mock对象被拷贝,原mock实例的ON_CALL配置不会作用到拷贝后的对象上。
  • unique_ptr的所有权处理失误:使用unique_ptr时,若未正确用ByMove转移所有权,会导致返回空指针;多次调用时未生成新的mock对象,也会因所有权已转移而返回空。
正确的Mock智能指针配置示例

先定义基础接口与Mock类:

// 核心接口定义
class Window {
public:
    virtual ~Window() = default;
    virtual bool isOpen() const = 0;
};

class CoreBuilder {
public:
    virtual ~CoreBuilder() = default;
    virtual std::shared_ptr<Window> createWindow() = 0;
    // 其他接口:createClock、createStateMachine等
};

// Mock类实现
class WindowMock : public Window {
public:
    MOCK_METHOD(bool, isOpen, (), (const, override));
};

class CoreBuilderMock : public CoreBuilder {
public:
    MOCK_METHOD(std::shared_ptr<Window>, createWindow, (), (override));
    // 对应其他接口的MOCK_METHOD
};

shared_ptr场景的测试代码

TEST(EngineTest, IsWindowOpen_ReturnsCorrectValue) {
    // 1. 创建mock对象并管理生命周期
    auto mockWindow = std::make_shared<WindowMock>();
    CoreBuilderMock mockBuilder;

    // 2. 严格匹配方法签名配置返回逻辑
    ON_CALL(mockBuilder, createWindow())
        .WillByDefault(Return(mockWindow));

    // 3. 传递mock对象给Engine(注意用引用/指针,避免拷贝)
    Engine sut(mockBuilder);

    // 4. 配置WindowMock的方法期望
    EXPECT_CALL(*mockWindow, isOpen())
        .WillOnce(Return(true));

    // 5. 执行测试断言
    ASSERT_TRUE(sut.isWindowOpen());
}

unique_ptr场景的测试代码

TEST(EngineTest, UniquePtrMock_WorksCorrectly) {
    CoreBuilderMock mockBuilder;

    // 配置返回unique_ptr时必须用ByMove转移所有权
    ON_CALL(mockBuilder, createWindow())
        .WillByDefault(Return(ByMove(std::make_unique<WindowMock>())));

    // 若需多次调用,每次生成新的mock对象
    // ON_CALL(mockBuilder, createWindow())
    //     .WillRepeatedly(Return(ByMove(std::make_unique<WindowMock>())));

    Engine sut(mockBuilder);
    // 后续测试逻辑...
}
关键注意事项
  • 严格匹配方法签名:检查CoreBuilder的createWindow是否为const成员函数,若原接口是virtual std::shared_ptr<Window> createWindow() const = 0;,则Mock类的MOCK_METHOD也需标记为const,ON_CALL的写法也要完全对应。
  • 禁止值传递Mock对象:Engine构造函数应接收CoreBuilder的引用或指针,避免拷贝导致Mock配置失效。
  • 验证Mock调用情况:添加EXPECT_CALL(mockBuilder, createWindow()).Times(1);,确认Engine在构造时确实调用了createWindow方法,排查构造逻辑是否存在问题。
  • unique_ptr所有权唯一:使用ByMove后,原unique_ptr会失效,若需多次返回,必须每次生成新的Mock对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 16:35:50