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

如何在GTest中Mock外部函数wfdEnumerateDevices以测试tt_init_device

两种Mock全局函数wfdEnumerateDevices的实现方案

方法1:接口封装依赖(推荐,符合代码可维护性原则)

步骤1:定义抽象接口类

把全局函数包装成抽象接口,让业务类依赖接口而非具体实现:

class WfdDeviceEnumerator {
public:
    virtual ~WfdDeviceEnumerator() = default;
    virtual bool enumerateDevices(void* a, int b, void* c) = 0;
};

步骤2:实现生产环境的真实调用类

在业务代码中,实现接口并调用真实的wfdEnumerateDevices:

class RealWfdDeviceEnumerator : public WfdDeviceEnumerator {
public:
    bool enumerateDevices(void* a, int b, void* c) override {
        return wfdEnumerateDevices(a, b, c);
    }
};

步骤3:修改业务类的依赖方式

让FusaTelltaleClientAppTh通过构造函数注入接口实例,默认使用真实实现:

class FusaTelltaleClientAppTh {
public:
    FusaTelltaleClientAppTh(int id, const std::string& name, 
                           std::unique_ptr<WfdDeviceEnumerator> enumerator = 
                               std::make_unique<RealWfdDeviceEnumerator>())
        : id_(id), name_(name), enumerator_(std::move(enumerator)) {}

    WFDErrorCode tt_init_device(void) {
        // ... 原有逻辑
        bool value = enumerator_->enumerateDevices(NULL, 0, NULL);
        // ... 根据value处理后续逻辑并返回对应错误码
    }

private:
    int id_;
    std::string name_;
    std::unique_ptr<WfdDeviceEnumerator> enumerator_;
};

步骤4:编写Google Mock类

用Google Mock创建接口的Mock实现:

#include <gmock/gmock.h>

class MockWfdDeviceEnumerator : public WfdDeviceEnumerator {
public:
    MOCK_METHOD3(enumerateDevices, bool(void*, int, void*));
};

步骤5:编写测试用例

注入Mock对象并设置期望返回值:

TEST_F(FusaAppTh, Sample_Success_WhenEnumerateReturnsTrue) {
    auto mockEnumerator = std::make_unique<MockWfdDeviceEnumerator>();
    // 设置调用参数和返回值期望
    EXPECT_CALL(*mockEnumerator, enumerateDevices(NULL, 0, NULL))
        .WillOnce(testing::Return(true));

    FusaTelltaleClientAppTh AppThObj(1, "abc", std::move(mockEnumerator));
    EXPECT_EQ(WFD_ERROR_NONE, AppThObj.tt_init_device());
}

TEST_F(FusaAppTh, Sample_Error_WhenEnumerateReturnsFalse) {
    auto mockEnumerator = std::make_unique<MockWfdDeviceEnumerator>();
    EXPECT_CALL(*mockEnumerator, enumerateDevices(NULL, 0, NULL))
        .WillOnce(testing::Return(false));

    FusaTelltaleClientAppTh AppThObj(1, "abc", std::move(mockEnumerator));
    // 根据实际业务逻辑,替换为对应的错误码
    EXPECT_EQ(WFD_ERROR_DEVICE_NOT_FOUND, AppThObj.tt_init_device());
}

方法2:直接Mock全局函数(适用于无法修改业务代码的场景)

步骤1:在测试文件中重定义全局函数

利用C++链接规则,让测试中的函数覆盖外部库的实现:

#include <gmock/gmock.h>

// 声明全局函数的Mock包装
testing::MockFunction<bool(void*, int, void*)> mockWfdEnumerateDevices;

// 重定义全局函数,转发到Mock对象
bool wfdEnumerateDevices(void* a, int b, void* c) {
    return mockWfdEnumerateDevices.Call(a, b, c);
}

步骤2:编写测试用例

直接设置Mock函数的返回期望:

TEST_F(FusaAppTh, Sample_Success_WhenEnumerateReturnsTrue) {
    EXPECT_CALL(mockWfdEnumerateDevices, Call(NULL, 0, NULL))
        .WillOnce(testing::Return(true));

    FusaTelltaleClientAppTh AppThObj(1, "abc");
    EXPECT_EQ(WFD_ERROR_NONE, AppThObj.tt_init_device());
}

TEST_F(FusaAppTh, Sample_Error_WhenEnumerateReturnsFalse) {
    EXPECT_CALL(mockWfdEnumerateDevices, Call(NULL, 0, NULL))
        .WillOnce(testing::Return(false));

    FusaTelltaleClientAppTh AppThObj(1, "abc");
    EXPECT_EQ(WFD_ERROR_DEVICE_NOT_FOUND, AppThObj.tt_init_device());
}

注意事项

  • 方法1遵循依赖倒置原则,代码扩展性和可维护性更强,优先推荐。
  • 方法2需要确保测试代码的链接优先级高于外部库,可能需要调整编译脚本的链接顺序。
  • 测试环境需提前配置好Google Test和Google Mock库。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 12:45:37